home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 191 / applic / topmap.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-11-20  |  72.3 KB  |  2,485 lines

  1. {*****************************************************************************}
  2. {*****************************************************************************}
  3. {                                                                             }
  4. {                     Fractal Topographical Maps v0.4                         }
  5. {                   Copyright (c) 1987 by Robert Adam II.                     }
  6. {                         All rights reserved.                                }
  7. {                                                                             }
  8. {*****************************************************************************}
  9. {*****************************************************************************}
  10. {                                                                             }
  11. {      WARNING:  This code is mostly uncommented and may be hazardous to      }
  12. {               your mental health.                                           }
  13. {                Don't blame me,  I warned you.                               }
  14. {                                                                             }
  15. {*****************************************************************************}
  16. {*****************************************************************************}
  17.  
  18. program TOPMAP;
  19.  
  20.   const
  21.     COPYRIGHT1 = ' Fractal Topographical Maps v0.4 ';
  22.     COPYRIGHT2 = ' Copyright (c) 1987 by Robert Adam II. ';
  23.     COPYRIGHT3 = ' All rights reserved. ';
  24.  
  25.     {$I A:\GEMCONST}
  26.     {$I A:\VDICONST}
  27.  
  28.     PI = 3.1415936535;
  29.  
  30.     MAP_SIZE = 65;
  31.  
  32.     WSX = 10;
  33.     WSY = 10;
  34.  
  35.     MAXXTILES = 3;
  36.     MAXYTILES = 2;
  37.  
  38.     MAXALTITUDE = 25000;
  39.     RMAXALTITUDE = 25000.0;
  40.  
  41.     DESK_TITLE = 3;
  42.  
  43. {*****************************************************************************}
  44.  
  45.   type
  46.     {$I A:\GEMTYPE}
  47.     {$I A:\VDITYPE}
  48.  
  49.     SHADOWREGION = record
  50.                      OX, OY  : integer;
  51.                      OHEIGHT,
  52.                      SLENGTH : real
  53.                    end;
  54.  
  55.     COLOR_VECTOR = array[ 0..15 ] of integer;
  56.  
  57.     MEMAREA     = array[ 1..16000 ] of integer;
  58.     MEMPTR      = ^MEMAREA;
  59.  
  60.     LONGITUDE   = array[ 1..MAP_SIZE ] of integer;
  61.     TILE_TYPE   = array[ 1..MAP_SIZE ] of LONGITUDE;
  62.     TILETYPE    = ^TILE_TYPE;
  63.     MAPTYPE     = array[ 1..MAXXTILES, 1..MAXYTILES ] of TILETYPE;
  64.  
  65.     POINT       = record
  66.                     X, Y : integer
  67.                   end;
  68.  
  69. {*****************************************************************************}
  70.  
  71.  
  72.   var
  73.     {$I A:\VDIVARS}
  74.  
  75.     MED_COL      : integer;
  76.  
  77.     FILL_PATTERN : FILL_PAT_TYPE;
  78.  
  79.     FUDGE       : real;
  80.     YINC,
  81.     SCALEX,
  82.     SCALEY,
  83.     SCALEW,
  84.     SCALEH,
  85.     REZ,
  86.     PIXEL_SIZE,             {  = 1;                             }
  87.     PMAP_SIZE,              {  = 65;    = MAP_SIZE * PIXEL_SIZE }
  88.     PMAP_SIZE2,             {  = 28;                            }
  89.     NUM_PLANES  : integer;  {  = 4;                             }
  90.  
  91.     HIGHEST,
  92.     LOWEST : integer;
  93.  
  94.     NUMLEVELS : integer;
  95.  
  96.     SIDE,
  97.     MAXX,
  98.     MAXY  : integer;
  99.  
  100.     REMAP_RANGE,
  101.     MAX_ALT_RANGE,              { maximum altitude range }
  102.     SUNANGLE,
  103.     TANGENT : real;
  104.  
  105.     DEF_PATH,
  106.     FILENAME : path_name;
  107.  
  108.     BRAND_NEW,
  109.     WATCH_ON,
  110.     SHADOW_ON : boolean;
  111.  
  112.     WX, WY : integer;
  113.  
  114.     MAP   : MAPTYPE;
  115.  
  116.     DUMMY : integer;
  117.  
  118.     QUANTUM : integer;
  119.  
  120.     XSCRN,
  121.     YSCRN,
  122.     WSCRN,
  123.     HSCRN : integer;
  124.  
  125.   { Window variables }
  126.     INFO_LINE,
  127.     MAIN_TITLE : window_title;
  128.     GRAPHICS_WINDOW : integer;
  129.  
  130.  
  131.   { Menu variables }
  132.     MENU : menu_ptr ;
  133.  
  134.     FILE_TITLE,
  135.     OPTIONS_TITLE,
  136.     VIEW_TITLE,
  137.     WIDTH_ITEM,
  138.     HEIGHT_ITEM,
  139.     REMAP_ITEM,
  140.     RESET_ITEM,
  141.     WATCH_ITEM,
  142.     WATER_ITEM,
  143.     SHADOW_ITEM,
  144.     NULL_ITEM,
  145.     NULL2_ITEM,
  146.     OLD_ITEM,
  147.     NEW_ITEM,
  148.     LOAD_ITEM,
  149.     SAVE_ITEM,
  150.     PERSPEC_ITEM,
  151.     SIDE_ITEM,
  152.     TOP_ITEM,
  153.     QUIT_ITEM : integer ;
  154.  
  155.     OSS_DIALOG,
  156.     ABOUT_DIALOG : dialog_ptr;
  157.  
  158.  
  159.   { mfdb variables }
  160.     PXY    : PXYARRAY;
  161.     MEMORY : MEMPTR;
  162.     S_MFDB,
  163.     D_MFDB : mfdbptr;
  164.  
  165.     NUMXTILES,
  166.     NUMYTILES : integer;
  167.  
  168.   { old color vector }
  169.     OLD_COLOR : COLOR_VECTOR;
  170.  
  171.     TREE_LEVEL,
  172.     WATER_LINE,
  173.     WATER_LEVEL : integer;
  174.     WATER_ON : boolean;
  175.     LEVELS : array[ 1..16 ] of integer;
  176.  
  177.     REMAP_ON,
  178.     SCALE_ON : boolean;
  179.  
  180.     SHADOWED_PLOT : boolean;
  181.  
  182.     COL_TO_MONO,
  183.     SCOL_TO_MONO,
  184.     SSCOL_TO_MONO,
  185.     BAND   : array[ 1..16 ] of integer;
  186.  
  187.     LIGHT,
  188.     SHADOW : array[ 1..7 ] of integer;
  189.  
  190.   {$I A:\GEMSUBS}
  191.   {$I A:\VDIPROC}
  192.  
  193. {*****************************************************************************}
  194. {*****************************************************************************}
  195. {*****************************************************************************}
  196.  
  197.   function QUICK_EXIT : boolean;
  198.     begin
  199.       AES_CALL( 79, INT_IN, INT_OUT, ADDR_IN, ADDR_OUT );
  200.       if (INT_OUT[ 3 ] & 3) <> 0
  201.       then
  202.         QUICK_EXIT := 1 = do_alert('[2][| Cancel?     |][Yes|No]',2)
  203.       else
  204.         QUICK_EXIT := false;
  205.     end;
  206.  
  207. {*****************************************************************************}
  208.  
  209.   function setcolor( COLORNUM, COLOR : integer ) : integer;
  210.     xbios( 7 );
  211.  
  212.   function GET_XCOLOR( COLORNUM : integer ) : integer;
  213.     begin
  214.       GET_XCOLOR := setcolor( COLORNUM, -1 );
  215.     end;
  216.  
  217.  
  218.   procedure SET_XCOLOR( COLORNUM, COLOR : integer);
  219.     var
  220.       DUMMY : integer;
  221.     begin
  222.       DUMMY := setcolor( COLORNUM, COLOR );
  223.     end;
  224.  
  225.  
  226.   procedure SAVE_COLORS;
  227.     var
  228.       COLORNUM : integer;
  229.     begin
  230.       for COLORNUM := 0 to 15 do
  231.         OLD_COLOR[ COLORNUM ] := GET_XCOLOR( COLORNUM );
  232.     end;
  233.  
  234.  
  235.   procedure RESTORE_COLORS;
  236.     var
  237.       COLORNUM : integer;
  238.     begin
  239.       for COLORNUM := 0 to 15 do
  240.         SET_XCOLOR( COLORNUM, OLD_COLOR[ COLORNUM ] );
  241.     end;
  242.  
  243.  
  244.   procedure SET_GEM_COLOR( COLORNUM, RED, GREEN, BLUE : integer );
  245.     begin
  246.       set_color( COLORNUM, RED*125, GREEN*125, BLUE*125 );
  247.     end;
  248.  
  249. {*****************************************************************************}
  250.  
  251.   function LEVEL_TO_MCOL( COL : integer ) : integer;
  252.     begin
  253.       if COL <= WATER_LEVEL
  254.       then
  255.         LEVEL_TO_MCOL := 2         { water }
  256.       else
  257.         if COL >= TREE_LEVEL
  258.         then
  259.           LEVEL_TO_MCOL := 1       { rocks and snow }
  260.         else
  261.           LEVEL_TO_MCOL := 3;      { plants }
  262.     end;
  263.  
  264. {*****************************************************************************}
  265.  
  266.   function GETREZ : integer;
  267.     XBIOS( 4 );
  268.  
  269.   procedure SET_PLOT_COLOR( COL : integer );
  270.     var
  271.       COLREG : integer;
  272.     begin
  273.       case REZ of
  274.         0 : paint_color( COL );
  275.         1,
  276.         2 : begin
  277.               if REZ = 2
  278.               then
  279.                 paint_color( 1 )
  280.               else
  281.                 paint_color( MED_COL );
  282.  
  283.               paint_outline( false );
  284.               if SHADOW_ON
  285.               then
  286.                 if SHADOWED_PLOT
  287.                 then
  288.                   COLREG := SCOL_TO_MONO[ COL ]
  289.                 else
  290.                   COLREG := SSCOL_TO_MONO[ COL ]
  291.               else
  292.                 COLREG := COL_TO_MONO[ COL ];
  293.  
  294.               if COLREG < 0
  295.               then
  296.                 vsf_interior( 4 )
  297.               else
  298.                 paint_style( COLREG );
  299.             end;
  300.       end;
  301.  
  302.     end;
  303.  
  304.  
  305. {*****************************************************************************}
  306.  
  307.   procedure DRAW_SCALE;
  308.   { draw the altitude color legend on the right of the window }
  309.     var
  310.       I,
  311.       Y,
  312.       HEIGHT : integer;
  313.     begin
  314.       paint_style( 1 );
  315.       paint_color( 1 );
  316.       paint_rect( SCALEX-(2*PIXEL_SIZE),
  317.                   SCALEY-(2*YINC),
  318.                   SCALEW+(4*PIXEL_SIZE),
  319.                   SCALEH+NUMLEVELS+(4*YINC)
  320.                 );
  321.  
  322.       Y := SCALEY;
  323.       for I := NUMLEVELS downto 1 do
  324.         begin
  325.           HEIGHT := round( (0.0 + LEVELS[ I ]) * SCALEH / RMAXALTITUDE );
  326.           if SHADOW_ON
  327.           then
  328.             begin
  329.               SHADOWED_PLOT := false;
  330.               MED_COL := LEVEL_TO_MCOL( I );
  331.               SET_PLOT_COLOR( LIGHT[ I ] );
  332.               paint_rect( SCALEX, Y, (SCALEW div 2), HEIGHT );
  333.               SHADOWED_PLOT := true;
  334.               SET_PLOT_COLOR( SHADOW[ I ] );
  335.               paint_rect( SCALEX+(SCALEW div 2), Y, (SCALEW div 2), HEIGHT );
  336.             end
  337.           else
  338.             begin
  339.               MED_COL := LEVEL_TO_MCOL( I );
  340.               SET_PLOT_COLOR( BAND[ I ] );
  341.               paint_rect( SCALEX, Y, SCALEW, HEIGHT );
  342.             end;
  343.  
  344.           Y := Y + HEIGHT + 1;
  345.         end;
  346.     end;
  347.  
  348.   procedure SET_NUMBER_OF_LEVELS;
  349.     var
  350.       I : integer;
  351.     begin
  352.       if SHADOW_ON
  353.       then
  354.         begin
  355.           NUMLEVELS   := 7;
  356.           WATER_LEVEL := 1;
  357.           TREE_LEVEL  := 5;
  358.           QUANTUM     := MAXALTITUDE div (NUMLEVELS + 2);
  359.           for I := 2 to NUMLEVELS do LEVELS[ I ] := QUANTUM;
  360.           LEVELS[ 1 ] := 3*QUANTUM;
  361.           WATER_LINE  := QUANTUM*3;
  362.         end
  363.       else
  364.         begin
  365.           NUMLEVELS   := 13;
  366.           WATER_LEVEL :=  4;
  367.           TREE_LEVEL  :=  9;
  368.           QUANTUM := MAXALTITUDE div NUMLEVELS;
  369.           for I := 1 to NUMLEVELS do LEVELS[ I ] := QUANTUM;
  370.           WATER_LINE  := QUANTUM*WATER_LEVEL;
  371.         end;
  372.     end;
  373.  
  374.   procedure SPECIAL_COLORS;
  375.     begin
  376.       case REZ of
  377.         0 : begin
  378.               SET_GEM_COLOR(  0, 7, 7, 7 );
  379.               SET_GEM_COLOR(  1, 0, 0, 0 );
  380.               SET_GEM_COLOR(  2, 5, 0, 0 );
  381.               SET_GEM_COLOR(  3, 0, 0, 3 );
  382.               SET_GEM_COLOR(  4, 5, 5, 5 );
  383.               SET_GEM_COLOR(  5, 2, 1, 0 );   { SIDE OF ISOMORPHIC }
  384.               SET_GEM_COLOR(  6, 3, 2, 0 );
  385.               SET_GEM_COLOR(  7, 1, 2, 0 );
  386.               SET_GEM_COLOR(  8, 0, 0, 5 );
  387.               SET_GEM_COLOR(  9, 0, 0, 7 );
  388.               SET_GEM_COLOR( 10, 0, 6, 0 );
  389.               SET_GEM_COLOR( 11, 0, 4, 0 );
  390.               SET_GEM_COLOR( 12, 2, 3, 0 );
  391.               SET_GEM_COLOR( 13, 5, 3, 1 );
  392.               SET_GEM_COLOR( 14, 6, 4, 1 );
  393.               SET_GEM_COLOR( 15, 6, 6, 6 );
  394.             end;
  395.         1 : begin
  396.               SET_GEM_COLOR(  0, 7, 7, 7 );
  397.               SET_GEM_COLOR(  1, 0, 0, 0 );
  398.               SET_GEM_COLOR(  2, 0, 0, 5 );
  399.               SET_GEM_COLOR(  3, 0, 2, 0 );
  400.             end;
  401.         2 : begin
  402.               SET_GEM_COLOR(  0, 7, 7, 7 );
  403.               SET_GEM_COLOR(  1, 0, 0, 0 );
  404.             end
  405.       end;
  406.  
  407.       SHADOW[ 1 ] :=  8;
  408.       SHADOW[ 2 ] := 11;
  409.       SHADOW[ 3 ] := 12;
  410.       SHADOW[ 4 ] :=  7;
  411.       SHADOW[ 5 ] :=  6;
  412.       SHADOW[ 6 ] := 13;
  413.       SHADOW[ 7 ] :=  4;
  414.  
  415.       LIGHT[ 1 ]  :=  9;
  416.       LIGHT[ 2 ]  := 10;
  417.       LIGHT[ 3 ]  := 11;
  418.       LIGHT[ 4 ]  := 12;
  419.       LIGHT[ 5 ]  := 13;
  420.       LIGHT[ 6 ]  := 14;
  421.       LIGHT[ 7 ]  := 15;
  422.  
  423.       BAND[  1 ] :=  1;
  424.       BAND[  2 ] :=  3;
  425.       BAND[  3 ] :=  8;
  426.       BAND[  4 ] :=  9;
  427.       BAND[  5 ] := 10;
  428.       BAND[  6 ] := 11;
  429.       BAND[  7 ] := 12;
  430.       BAND[  8 ] :=  7;
  431.       BAND[  9 ] :=  6;
  432.       BAND[ 10 ] := 13;
  433.       BAND[ 11 ] := 14;
  434.       BAND[ 12 ] :=  4;
  435.       BAND[ 13 ] := 15;
  436.  
  437.       COL_TO_MONO[  1 ] :=  9;
  438.       COL_TO_MONO[  2 ] :=  1; { not used }
  439.       COL_TO_MONO[  3 ] :=  8;
  440.       COL_TO_MONO[  4 ] := 16;
  441.       COL_TO_MONO[  5 ] :=  8; { not used }
  442.       COL_TO_MONO[  6 ] := 15;
  443.       COL_TO_MONO[  7 ] :=  2;
  444.       COL_TO_MONO[  8 ] :=  7;
  445.       COL_TO_MONO[  9 ] :=  6;
  446.       COL_TO_MONO[ 10 ] :=  5;
  447.       COL_TO_MONO[ 11 ] :=  4;
  448.       COL_TO_MONO[ 12 ] :=  3;
  449.       COL_TO_MONO[ 13 ] := 14;
  450.       COL_TO_MONO[ 14 ] := 12;
  451.       COL_TO_MONO[ 15 ] :=  0;
  452.       COL_TO_MONO[ 16 ] :=  1; { not used }
  453.       SSCOL_TO_MONO[  1 ] := 10; { not used }
  454.       SSCOL_TO_MONO[  2 ] := 26; { not used }
  455.       SSCOL_TO_MONO[  3 ] :=  1; { not used }
  456.       SSCOL_TO_MONO[  4 ] :=  2;
  457.       SSCOL_TO_MONO[  5 ] :=  8;
  458.       SSCOL_TO_MONO[  6 ] :=  5;
  459.       SSCOL_TO_MONO[  7 ] :=  6;
  460.       SSCOL_TO_MONO[  8 ] :=  9;
  461.       SSCOL_TO_MONO[  9 ] := -1;
  462.       SSCOL_TO_MONO[ 10 ] :=  7;
  463.       SSCOL_TO_MONO[ 11 ] :=  6;
  464.       SSCOL_TO_MONO[ 12 ] :=  5;
  465.       SSCOL_TO_MONO[ 13 ] :=  4;
  466.       SSCOL_TO_MONO[ 14 ] :=  2;
  467.       SSCOL_TO_MONO[ 15 ] :=  0;
  468.       SSCOL_TO_MONO[ 16 ] :=  1; { not used }
  469.       SCOL_TO_MONO[  1 ] := 10; { not used }
  470.       SCOL_TO_MONO[  2 ] := 26; { not used }
  471.       SCOL_TO_MONO[  3 ] :=  1; { not used }
  472.       SCOL_TO_MONO[  4 ] :=  2;
  473.       SCOL_TO_MONO[  5 ] :=  8;
  474.       SCOL_TO_MONO[  6 ] :=  5;
  475.       SCOL_TO_MONO[  7 ] :=  6;
  476.       SCOL_TO_MONO[  8 ] :=  9;
  477.       SCOL_TO_MONO[  9 ] :=  8;
  478.       SCOL_TO_MONO[ 10 ] :=  7;
  479.       SCOL_TO_MONO[ 11 ] :=  8;
  480.       SCOL_TO_MONO[ 12 ] :=  7;
  481.       SCOL_TO_MONO[ 13 ] :=  4;
  482.       SCOL_TO_MONO[ 14 ] :=  2;
  483.       SCOL_TO_MONO[ 15 ] :=  0;
  484.       SCOL_TO_MONO[ 16 ] :=  1; { not used }
  485.       FILL_PATTERN[  1 ] := $BF7F;
  486.       FILL_PATTERN[  2 ] := $DEDD;
  487.       FILL_PATTERN[  3 ] := $F7FB;
  488.       FILL_PATTERN[  4 ] := $FFFF;
  489.  
  490.       FILL_PATTERN[  5 ] := $EFDF;
  491.       FILL_PATTERN[  6 ] := $BB77;
  492.       FILL_PATTERN[  7 ] := $FDFE;
  493.       FILL_PATTERN[  8 ] := $FFFF;
  494.  
  495.       FILL_PATTERN[  9 ] := $F7FB;
  496.       FILL_PATTERN[ 10 ] := $DDED;
  497.       FILL_PATTERN[ 11 ] := $7FBF;
  498.       FILL_PATTERN[ 12 ] := $FFFF;
  499.  
  500.       FILL_PATTERN[ 13 ] := $FEFD;
  501.       FILL_PATTERN[ 14 ] := $B77B;
  502.       FILL_PATTERN[ 15 ] := $EFDF;
  503.       FILL_PATTERN[ 16 ] := $FFFF;
  504.  
  505.       vsf_updat( FILL_PATTERN );
  506.     end;
  507.  
  508.  
  509.   procedure SET_SPECIAL_COLORS;
  510.     begin
  511.       SPECIAL_COLORS;
  512.       SET_NUMBER_OF_LEVELS;
  513.     end;
  514.  
  515. {*****************************************************************************}
  516.  
  517.   function min( INT1, INT2 : integer ) : integer;
  518.     begin
  519.       if INT1 > INT2
  520.       then
  521.         min := INT2
  522.       else
  523.         min := INT1;
  524.     end;
  525.  
  526.  
  527.   function max( INT1, INT2 : integer ) : integer;
  528.     begin
  529.       if INT1 >= INT2
  530.       then
  531.         max := INT1
  532.       else
  533.         max := INT2;
  534.     end;
  535.  
  536.  
  537. {*****************************************************************************}
  538. {  The following routines are used to save the graphics window and then       }
  539. { restore portions of it during window redraw.                                }
  540. {*****************************************************************************}
  541.  
  542.   function MEMPTR_TO_LINT( PNTR : MEMPTR ) : long_integer;
  543.     var
  544.       COERCE : record
  545.                  case boolean of
  546.                    false : ( PTR : MEMPTR );
  547.                    true  : ( ADR : long_integer );
  548.                end;
  549.     begin
  550.       COERCE.PTR := PNTR;
  551.       MEMPTR_TO_LINT := COERCE.ADR;
  552.     end;
  553.  
  554.  
  555.   procedure READY_MFDB;
  556.     begin
  557.       S_MFDB^.MP  := MEMPTR_TO_LINT( MEMORY );
  558.       S_MFDB^.FWP := WSCRN;
  559.       S_MFDB^.FH  := HSCRN;
  560.       S_MFDB^.FWW := (WSCRN div 16);
  561.       S_MFDB^.FF  := 0;
  562.       S_MFDB^.NP  := NUM_PLANES;
  563.       S_MFDB^.R1  := 0;
  564.       S_MFDB^.R2  := 0;
  565.       S_MFDB^.R3  := 0;
  566.  
  567.       D_MFDB^.MP  := 0;
  568.     end;
  569.  
  570.  
  571.   procedure SAVE_AREA( X, Y, W, H : integer );
  572.     begin
  573.       begin_update; hide_mouse;
  574.  
  575.       PXY[ 0 ] := X;            PXY[ 1 ] := Y;
  576.       PXY[ 2 ] := X+W-1;        PXY[ 3 ] := Y+H-1;
  577.       PXY[ 4 ] := X;            PXY[ 5 ] := Y;
  578.       PXY[ 6 ] := X+W-1;        PXY[ 7 ] := Y+H-1;
  579.  
  580.       vro_cpyform( 3, PXY, D_MFDB, S_MFDB );
  581.  
  582.       show_mouse;   end_update;
  583.     end;
  584.  
  585.  
  586.   procedure RESTORE_AREA( X, Y, W, H : integer );
  587.     begin
  588.       begin_update; hide_mouse;
  589.  
  590.       PXY[ 0 ] := X;            PXY[ 1 ] := Y;
  591.       PXY[ 2 ] := X+W-1;        PXY[ 3 ] := Y+H-1;
  592.       PXY[ 4 ] := X;            PXY[ 5 ] := Y;
  593.       PXY[ 6 ] := X+W-1;        PXY[ 7 ] := Y+H-1;
  594.  
  595.       vro_cpyform( 3, PXY, S_MFDB, D_MFDB );
  596.  
  597.       show_mouse;   end_update;
  598.     end;
  599.  
  600.  
  601.   procedure COPY_AREA( XF, YF, WF, HF, XT, YT, WT, HT : integer );
  602.     begin
  603.       PXY[ 0 ] := XF;           PXY[ 1 ] := YF;
  604.       PXY[ 2 ] := WF;           PXY[ 3 ] := HF;
  605.       PXY[ 4 ] := XT;           PXY[ 5 ] := YT;
  606.       PXY[ 6 ] := WT;           PXY[ 7 ] := HT;
  607.       D_MFDB^.MP := 0;
  608.       vro_cpyform( 3, PXY, D_MFDB, D_MFDB );
  609.     end;
  610.  
  611. {*****************************************************************************}
  612.  
  613.   function RANDOM24 : long_integer;
  614.     XBIOS( 17 );
  615.  
  616.  
  617.   function RANDOM( MINR, MAXR : integer ) : integer;
  618.     begin
  619.       RANDOM := trunc( RANDOM24 * (MAXR - MINR + 1.0) / $00FFFFFF ) + MINR;
  620.     end;
  621.  
  622. {*****************************************************************************}
  623.  
  624.   procedure CLEAR_MAP_AREA;
  625.     begin
  626.       set_window( GRAPHICS_WINDOW );
  627.       paint_color( 1 );
  628.       paint_rect( WSX-(2*PIXEL_SIZE),
  629.                   WSY-(2*YINC),
  630.                   ((NUMXTILES*(MAP_SIZE-1))+5)*PIXEL_SIZE,
  631.                   ((NUMYTILES*(MAP_SIZE-1))+5)*YINC
  632.                 );
  633.       paint_color( 0 );
  634.       paint_rect( WSX, WSY,
  635.                   ((NUMXTILES*(MAP_SIZE-1))+1)*PIXEL_SIZE,
  636.                   ((NUMYTILES*(MAP_SIZE-1))+1)*YINC
  637.                 );
  638.  
  639.     end;
  640.  
  641.  
  642.   procedure FLATTEN_MAP( var MAP : MAPTYPE );
  643.   {                                                                           }
  644.   { Fill the map with an illegal value (-1) so that you can later distinguish }
  645.   { between a used and unused location.                                       }
  646.   {                                                                           }
  647.     var
  648.       TILEX, TILEY,
  649.       X, Y : integer;
  650.     begin
  651.       for TILEX := 1 to NUMXTILES do
  652.         for TILEY := 1 to NUMYTILES do
  653.           for X := 1 to MAP_SIZE do
  654.             for Y := 1 to MAP_SIZE do
  655.               MAP[ TILEX, TILEY ]^[ X, Y ] := -1;
  656.     end;
  657.  
  658.   function REMAP_ALT( ALT : integer ) : integer;
  659.     begin
  660.       REMAP_ALT := round( (ALT - (LOWEST+1)) * RMAXALTITUDE / REMAP_RANGE );
  661.     end;
  662.  
  663.   function ALT_TO_COL( ALT : integer ): integer;
  664.   {                                                                           }
  665.   { this function maps an altitude to a color                                 }
  666.   {                                                                           }
  667.     var
  668.       COL : integer;
  669.     begin
  670.       if REMAP_ON
  671.       then
  672.         ALT := REMAP_ALT( ALT );
  673.  
  674.       COL := 1;
  675.       loop
  676.         ALT := ALT - LEVELS[ COL ]
  677.       exit if (ALT <= 0) or (COL >= NUMLEVELS);
  678.         COL := COL + 1
  679.       end;
  680.  
  681.       if WATER_ON
  682.       then
  683.         ALT_TO_COL := max( WATER_LEVEL, COL )
  684.       else
  685.         ALT_TO_COL := COL;
  686.  
  687.       MED_COL := LEVEL_TO_MCOL( COL );
  688.     end;
  689.  
  690.  
  691.   procedure PLOT_LOCATION( var MAP : TILETYPE;
  692.                            LOCATION : POINT
  693.                          );
  694.   {                                                                    }
  695.   { Plots a pixel during the creation of the map if WATCH is turned on }
  696.   {                                                                    }
  697.     begin
  698.       if WATCH_ON
  699.       then
  700.         with LOCATION do
  701.           begin
  702.             if SHADOW_ON
  703.             then
  704.               SET_PLOT_COLOR( LIGHT[ALT_TO_COL( MAP^[ X, Y ] )] )
  705.             else
  706.               SET_PLOT_COLOR( BAND[ ALT_TO_COL( MAP^[ X, Y ] )] );
  707.  
  708.             paint_rect( WX+PIXEL_SIZE*(X-1), WY+YINC*(Y-1),
  709.                         PIXEL_SIZE, YINC
  710.                       );
  711.           end;
  712.     end;
  713.  
  714.  
  715.   function USED_LOCATION( var MAP : TILETYPE;
  716.                           LOCATION : POINT
  717.                         ) : boolean;
  718.   {                                                                           }
  719.   { returns true if the location has been assigned an altitude                }
  720.   { returns false otherwise                                                   }
  721.   {                                                                           }
  722.     begin
  723.       USED_LOCATION := MAP^[ LOCATION.X, LOCATION.Y ] >= 0;
  724.     end;
  725.  
  726.  
  727.   procedure RANDOM_POINT( var MAP : TILETYPE;   { one tile of the map         }
  728.                               LOCATION : POINT; { location to assign altitude }
  729.                               LOWER,            { lower bound of region       }
  730.                               UPPER : integer   { upper bound of region       }
  731.                         );
  732.   { assign a random altitude within the specified range to the location on }
  733.   { the map specified if the location has not yet been used                }
  734.     begin
  735.       if not USED_LOCATION( MAP, LOCATION )
  736.       then
  737.         with LOCATION do
  738.           MAP^[ X, Y ] := RANDOM( LOWER, UPPER );
  739.     end;
  740.  
  741.   procedure GET_BOUNDS( var LOW, HIGH : integer );
  742.     var
  743.       ANSWER : integer;
  744.     begin
  745. {          HI_BOUND  := MAXALTITUDE - LOW_BOUND; }
  746.       ANSWER := do_alert('[2][| High bound? |][L|M|H]',2);
  747.       case ANSWER of
  748.         1 : HIGH := MAXALTITUDE - (QUANTUM * 3);
  749.         2 : HIGH := MAXALTITUDE - (QUANTUM * 2);
  750.         3 : HIGH := MAXALTITUDE - QUANTUM;
  751.       end;
  752.  
  753. {          LOW_BOUND := trunc( QUANTUM * 2.00 ); }
  754.       ANSWER := do_alert('[2][| Low bound? |][L|M|H]',2);
  755.       case ANSWER of
  756.         1 : LOW := QUANTUM;
  757.         2 : LOW := QUANTUM * 2;
  758.         3 : LOW := QUANTUM * 3;
  759.       end;
  760.     end;
  761.  
  762.   procedure CHECK_RANGE( var VALUE : integer );
  763.     begin
  764.       HIGHEST := max( HIGHEST, VALUE );
  765.       LOWEST  := min( LOWEST,  VALUE );
  766.       VALUE := min( max( 0, VALUE ), MAXALTITUDE );
  767.     end;
  768.  
  769.   procedure DEFINE_START( var MAP : MAPTYPE );
  770.   {                                                                           }
  771.   { assigns values to the seed points of the tiles (the corners)              }
  772.   {                                                                           }
  773.     var
  774.       TILEX, TILEY,
  775.       LOW_BOUND, HI_BOUND : integer;
  776.       PNT,MID : POINT;
  777.     begin
  778.       if do_alert('[2][| Use preset range? |][Yes|No]',1) = 1
  779.       then
  780.         begin
  781.           LOW_BOUND := 1;
  782.           HI_BOUND  := MAXALTITUDE;
  783.         end
  784.       else
  785.         GET_BOUNDS( LOW_BOUND, HI_BOUND );
  786.  
  787.       LOWEST := MAXALTITUDE;  HIGHEST := 0;
  788.  
  789.       MAX_ALT_RANGE := (HI_BOUND - LOW_BOUND) + 1;
  790.       MID.X := 1 + (MAP_SIZE div 2);  MID.Y := 1 + (MAP_SIZE div 2);
  791.  
  792.       for TILEY := 1 to NUMYTILES do
  793.         begin
  794.           PNT.X := 1;  PNT.Y := 1;
  795.           for TILEX := 1 to NUMXTILES do
  796.             begin
  797.               if RANDOM( 1, 100 ) < 30
  798.               then
  799.                 begin
  800.                  RANDOM_POINT( MAP[ TILEX, TILEY ], MID, LOW_BOUND, HI_BOUND );
  801.                  CHECK_RANGE( MAP[ TILEX, TILEY ]^[MID.X, MID.Y] );
  802.                 end;
  803.  
  804.               RANDOM_POINT( MAP[ TILEX, TILEY ], PNT, LOW_BOUND, HI_BOUND );
  805.               CHECK_RANGE( MAP[ TILEX, TILEY ]^[PNT.X, PNT.Y] );
  806.               if TILEX > 1
  807.               then
  808.                 MAP[ TILEX-1, TILEY ]^[ MAP_SIZE, 1 ]
  809.                   := MAP[ TILEX, TILEY ]^[ 1, 1 ];
  810.               if TILEY > 1
  811.               then
  812.                 begin
  813.                   MAP[ TILEX, TILEY-1 ]^[ 1, MAP_SIZE ]
  814.                     := MAP[ TILEX, TILEY ]^[ 1, 1 ];
  815.                   if TILEX > 1
  816.                   then
  817.                     MAP[ TILEX-1, TILEY-1 ]^[ MAP_SIZE, MAP_SIZE ]
  818.                       := MAP[ TILEX, TILEY ]^[ 1, 1 ];
  819.                 end;
  820.             end;
  821.  
  822.           PNT.X := MAP_SIZE;
  823.           RANDOM_POINT( MAP[ NUMXTILES, TILEY ], PNT, LOW_BOUND, HI_BOUND );
  824.           CHECK_RANGE( MAP[ NUMXTILES, TILEY ]^[PNT.X, PNT.Y] );
  825.           if TILEY > 1
  826.           then
  827.             MAP[ NUMXTILES, TILEY-1 ]^[ 1, MAP_SIZE ]
  828.               := MAP[ NUMXTILES, TILEY ]^[ 1, 1 ];
  829.         end;
  830.  
  831.       PNT.X := 1;  PNT.Y := MAP_SIZE;
  832.       for TILEX := 1 to NUMXTILES do
  833.         begin
  834.           RANDOM_POINT( MAP[ TILEX, NUMYTILES ], PNT, LOW_BOUND, HI_BOUND );
  835.           CHECK_RANGE( MAP[ TILEX, NUMYTILES ]^[PNT.X,PNT.Y] );
  836.           if TILEX > 1
  837.           then
  838.             MAP[ TILEX-1, NUMYTILES ]^[ MAP_SIZE, MAP_SIZE ]
  839.               := MAP[ TILEX, NUMYTILES ]^[ 1, MAP_SIZE ];
  840.         end;
  841.       PNT.X := MAP_SIZE;
  842.       RANDOM_POINT( MAP[ NUMXTILES, NUMYTILES ], PNT, LOW_BOUND, HI_BOUND );
  843.       CHECK_RANGE( MAP[ NUMXTILES, NUMYTILES ]^[PNT.X,PNT.Y] );
  844.     end;
  845.  
  846.  
  847.   procedure NEW_HORIZONTAL( var MAP : TILETYPE; { one tile of the map }
  848.                                 LEFT,           { Left point of top or bottom }
  849.                                 RIGHT : POINT;  { Right point of top or bottom}
  850.                             var MID : POINT     { Middle point of line }
  851.                           );
  852.     var
  853.       DIFF,
  854.       LEFT_ALT, RIGHT_ALT, MID_ALT
  855.        : integer;
  856.     begin
  857.       MID.Y := LEFT.Y;
  858.       MID.X := LEFT.X + ((RIGHT.X - LEFT.X) div 2);
  859.  
  860.       if not USED_LOCATION( MAP, MID )
  861.       then
  862.         begin
  863.           LEFT_ALT  := MAP^[ LEFT.X, LEFT.Y ];
  864.           RIGHT_ALT := MAP^[ RIGHT.X, RIGHT.Y ];
  865.           DIFF := abs( LEFT_ALT - RIGHT_ALT );
  866.           MID_ALT := min( LEFT_ALT, RIGHT_ALT ) + (DIFF div 2);
  867.           DIFF := trunc( (RIGHT.X - LEFT.X) * MAX_ALT_RANGE / MAP_SIZE);
  868.           DIFF := (DIFF div 2) - RANDOM( 0, DIFF );
  869.           if (DIFF > 0) and
  870.              ((MAXALTITUDE-MID_ALT) < DIFF)
  871.           then
  872.             DIFF := MAXALTITUDE - MID_ALT;
  873.  
  874.           MAP^[ MID.X, MID.Y ] := max( 0, (MID_ALT + DIFF) );
  875.         end;
  876.     end;
  877.  
  878.  
  879.   procedure NEW_VERTICAL( var MAP : TILETYPE;  { one tile of the map      }
  880.                               TOP,             { Top point of a side      }
  881.                               BOT : POINT;     { Bottom point of a side   }
  882.                           var MID : POINT      { Middle point of the side }
  883.                         );
  884.     var
  885.       DIFF,
  886.       TOP_ALT, BOT_ALT, MID_ALT : integer;
  887.     begin
  888.       MID.X := TOP.X;
  889.       MID.Y := TOP.Y + ((BOT.Y - TOP.Y) div 2);
  890.  
  891.       if not USED_LOCATION( MAP, MID )
  892.       then
  893.         begin
  894.           TOP_ALT := MAP^[ TOP.X, TOP.Y ];
  895.           BOT_ALT := MAP^[ BOT.X, BOT.Y ];
  896.           DIFF := abs( TOP_ALT - BOT_ALT );
  897.           MID_ALT := min( TOP_ALT, BOT_ALT ) + (DIFF div 2);
  898.           DIFF := trunc( (BOT.Y - TOP.Y) * MAX_ALT_RANGE / MAP_SIZE );
  899.           DIFF := (DIFF div 2) - RANDOM( 0, DIFF );
  900.           if (DIFF > 0) and
  901.              ((MAXALTITUDE-MID_ALT) < DIFF)
  902.           then
  903.             DIFF := MAXALTITUDE - MID_ALT;
  904.  
  905.           MAP^[ MID.X, MID.Y ] := max( 0, (MID_ALT + DIFF) );
  906.         end;
  907.     end;
  908.  
  909.  
  910.   procedure NEW_CENTER( var MAP : TILETYPE;  { one tile of the map      }
  911.                             TM,              { Top Middle point         }
  912.                             RM,              { Right Middle point       }
  913.                             BM,              { Bottom Middle point      }
  914.                             LM : POINT;      { Left Middle point        }
  915.                         var CENTER : POINT   { Center point             }
  916.                       );
  917.     var
  918.       DIFF,
  919.       TOP_ALT, BOT_ALT, RIGHT_ALT, LEFT_ALT, MAX_ALT, MIN_ALT,
  920.       AVERAGE1, AVERAGE2, AVERAGE : integer;
  921.     begin
  922.       CENTER.X := TM.X;
  923.       CENTER.Y := LM.Y;
  924.  
  925.       if not USED_LOCATION( MAP, CENTER )
  926.       then
  927.         begin
  928.           TOP_ALT := MAP^[ TM.X, TM.Y ];
  929.           BOT_ALT := MAP^[ BM.X, BM.Y ];
  930.           RIGHT_ALT := MAP^[ RM.X, RM.Y ];
  931.           LEFT_ALT := MAP^[ LM.X, LM.Y ];
  932.           AVERAGE1 := trunc( (TOP_ALT*1.0 + BOT_ALT) / 2 );
  933.           AVERAGE2 := trunc( (RIGHT_ALT*1.0 + LEFT_ALT) / 2 );
  934.           AVERAGE := trunc( (AVERAGE1*1.0 + AVERAGE2) / 2 );
  935.           DIFF := trunc( (BM.Y - TM.Y) * MAX_ALT_RANGE / MAP_SIZE );
  936.           DIFF := (DIFF div 2) - RANDOM( 0, DIFF );
  937.           if (DIFF > 0) and
  938.              ((MAXALTITUDE-AVERAGE) < DIFF)
  939.           then
  940.             DIFF := MAXALTITUDE - (AVERAGE+1);
  941.  
  942.           MAP^[ CENTER.X, CENTER.Y ] := max( 0, (AVERAGE + DIFF) );
  943.         end;
  944.     end;
  945.  
  946.   procedure EVOLVE_LANDSCAPE( var MAP : TILETYPE; { one tile of the map }
  947.                                   TL,             { Top Left     corner }
  948.                                   TR,             { Top Right    corner }
  949.                                   BR,             { Bottom Right corner }
  950.                                   BL : POINT;     { Bottom Left  corner }
  951.                               var CANCEL_IT : boolean
  952.                             );
  953.     var
  954.       TM, RM, BM, LM, CENTER : POINT;
  955.       I, TMP, TWIDDLE : integer;
  956.       SPLAY : array[ 1..4 ] of 1..4;
  957.     begin
  958.       if not CANCEL_IT
  959.       then
  960.         begin
  961.           if ((TR.X - TL.X) > 1) or
  962.              ((BR.Y - TR.Y) > 1)
  963.           then
  964.             begin
  965.               NEW_HORIZONTAL( MAP, TL, TR, TM );
  966.               CHECK_RANGE( MAP^[ TM.X, TM.Y ] );
  967.               NEW_HORIZONTAL( MAP, BL, BR, BM );
  968.               CHECK_RANGE( MAP^[ BM.X, BM.Y ] );
  969.               NEW_VERTICAL( MAP, TL, BL, LM );
  970.               CHECK_RANGE( MAP^[ LM.X, LM.Y ] );
  971.               NEW_VERTICAL( MAP, TR, BR, RM );
  972.               CHECK_RANGE( MAP^[ RM.X, RM.Y ] );
  973.               NEW_CENTER( MAP, TM, RM, BM, LM, CENTER );
  974.               CHECK_RANGE( MAP^[ CENTER.X, CENTER.Y ] );
  975.  
  976. { randomize the splay array }
  977.               for I := 1 to 4 do SPLAY[ I ] := I;
  978.                 for I := 1 to 10 do
  979.                   begin
  980.                     TMP := SPLAY[ 1 ];
  981.                     TWIDDLE := RANDOM( 1, 4 );
  982.                     SPLAY[ 1 ] := SPLAY[ TWIDDLE ];
  983.                     SPLAY[ TWIDDLE ] := TMP;
  984.                   end;
  985.  
  986. { evolve the four subrectangles }
  987.               I := 1;
  988.               repeat
  989.                 CANCEL_IT := QUICK_EXIT;
  990.                 case SPLAY[ I ] of
  991.                   1 : EVOLVE_LANDSCAPE( MAP, TL, TM, CENTER, LM, CANCEL_IT );
  992.                   2 : EVOLVE_LANDSCAPE( MAP, TM, TR, RM, CENTER, CANCEL_IT );
  993.                   3 : EVOLVE_LANDSCAPE( MAP, LM, CENTER, BM, BL, CANCEL_IT );
  994.                   4 : EVOLVE_LANDSCAPE( MAP, CENTER, RM, BR, BM, CANCEL_IT )
  995.                 end;
  996.                 I := I + 1;
  997.               until (I > 4) or CANCEL_IT;
  998.             end;
  999.  
  1000. { show the points }
  1001.           if not CANCEL_IT
  1002.           then
  1003.             begin
  1004.               PLOT_LOCATION( MAP, TL );
  1005.               PLOT_LOCATION( MAP, TR );
  1006.               PLOT_LOCATION( MAP, BR );
  1007.               PLOT_LOCATION( MAP, BL );
  1008.             end;
  1009.         end;
  1010.     end;
  1011.  
  1012.  
  1013.   procedure INIT_GWINDOW;
  1014.     var
  1015.       X, Y, H, W : integer;
  1016.  
  1017.     begin
  1018.       hide_mouse;
  1019.       bring_to_front( GRAPHICS_WINDOW );
  1020.       draw_mode( 1 );
  1021.       paint_style( 1 );
  1022.       paint_color( 0 );
  1023.       work_rect( GRAPHICS_WINDOW, X, Y, W, H );
  1024.       set_clip( X, Y, W, H );
  1025.       set_window( GRAPHICS_WINDOW );
  1026.       paint_rect( 0, 0, W, H );
  1027.       FLATTEN_MAP( MAP );
  1028.       CLEAR_MAP_AREA;
  1029.       DRAW_SCALE;
  1030.       SAVE_AREA( X, Y, W, H );
  1031.       show_mouse;
  1032.     end;
  1033.  
  1034.  
  1035.   procedure REDRAW_MAP( var MAP : MAPTYPE );
  1036.   forward;
  1037.  
  1038.  
  1039.   procedure DRAW_MAP( var MAP : MAPTYPE );
  1040.     var
  1041.       TL, TR, BR, BL : POINT;
  1042.       I,
  1043.       TILEX, TILEY : integer;
  1044.       SAVE_REMAP,
  1045.       CANCEL_IT : boolean;
  1046.     begin
  1047.       bring_to_front( GRAPHICS_WINDOW );
  1048.       INIT_GWINDOW;
  1049.       SAVE_REMAP := REMAP_ON; REMAP_ON := false;
  1050.       DEFINE_START( MAP );
  1051.       TL.X := 1;        TL.Y := 1;
  1052.       TR.X := MAP_SIZE; TR.Y := 1;
  1053.       BR.X := MAP_SIZE; BR.Y := MAP_SIZE;
  1054.       BL.X := 1;        BL.Y := MAP_SIZE;
  1055.       CANCEL_IT := FALSE;
  1056.       SHADOWED_PLOT := false;
  1057.       begin_update; hide_mouse;
  1058.       TILEX := 1;
  1059.       repeat
  1060.         WX := WSX + ((TILEX-1) * (PMAP_SIZE-PIXEL_SIZE));
  1061.         TILEY := 1;
  1062.         repeat
  1063.           WY := WSY + ((TILEY-1) * ((MAP_SIZE-1)*YINC));
  1064.           if (TILEY-1) >= 1
  1065.           then
  1066.             for I := 1 to MAP_SIZE do
  1067.               MAP[ TILEX, TILEY ]^[ I, 1 ]
  1068.                  := MAP[ TILEX, TILEY-1 ]^[ I, MAP_SIZE ];
  1069.  
  1070.           if (TILEX-1) >= 1
  1071.           then
  1072.             for I := 1 to MAP_SIZE do
  1073.               MAP[ TILEX, TILEY ]^[ 1, I ]
  1074.                 := MAP[ TILEX-1, TILEY ]^[ MAP_SIZE, I ];
  1075.  
  1076.           EVOLVE_LANDSCAPE( MAP[ TILEX, TILEY ], TL, TR, BR, BL, CANCEL_IT );
  1077.  
  1078.           TILEY := TILEY + 1;
  1079.         until (TILEY > NUMYTILES) or CANCEL_IT;
  1080.  
  1081.         TILEX := TILEX + 1;
  1082.       until (TILEX > NUMXTILES) or CANCEL_IT;
  1083.  
  1084.       SAVE_AREA( XSCRN, YSCRN, WSCRN, HSCRN );
  1085.       show_mouse; end_update;
  1086.  
  1087.       REMAP_ON := SAVE_REMAP;
  1088.       menu_enable( MENU, REMAP_ITEM );
  1089.       REMAP_RANGE := (HIGHEST - LOWEST) + 1;
  1090.  
  1091.  
  1092.       BRAND_NEW := true;
  1093.       if SHADOW_ON and not CANCEL_IT
  1094.       then
  1095.         if do_alert('[2][| Add shadows?  |][Yes|No]',1) = 1
  1096.         then
  1097.           REDRAW_MAP( MAP );
  1098.       BRAND_NEW := false;
  1099.  
  1100.     end;
  1101.  
  1102. {*****************************************************************************}
  1103.  
  1104.   procedure ENLIGHTEN( var SHADOW_REGION : SHADOWREGION );
  1105.   { sets the shadow to the shadow of an object of zero height }
  1106.     begin
  1107.       with SHADOW_REGION do
  1108.         begin
  1109.            OHEIGHT := 0;
  1110.            OX := 1;  OY := 1;
  1111.            SLENGTH := 0;
  1112.         end;
  1113.     end;
  1114.  
  1115.   procedure SIDE_COLOR;
  1116.     begin
  1117.       case REZ of
  1118.         0 : SET_PLOT_COLOR( 5 );
  1119.         1 : begin
  1120.               paint_color( 1 );
  1121.               paint_outline( false );
  1122.               paint_style( 26 );
  1123.             end;
  1124.         2 : begin
  1125.               paint_color( 1 );
  1126.               paint_outline( false );
  1127.               paint_style( 26 );
  1128.             end;
  1129.       end;
  1130.     end;
  1131.  
  1132.   procedure FRONT_COLOR;
  1133.     begin
  1134.       case REZ of
  1135.         0 : SET_PLOT_COLOR( SHADOW[ 5 ] );
  1136.         1 : begin
  1137.               paint_color( 1 );
  1138.               paint_outline( false );
  1139.               paint_style( 10 );
  1140.             end;
  1141.         2 : begin
  1142.               paint_color( 1 );
  1143.               paint_outline( false );
  1144.               paint_style( 10 );
  1145.             end;
  1146.       end;
  1147.     end;
  1148.  
  1149.  
  1150.   procedure PLOT_SRECT( var MAP : MAPTYPE;
  1151.                             IX, IY, TX, TY, XX, YY,
  1152.                             XPNT, YPNT, MAXX, MAXY : integer;
  1153.                         var SHADOW_REGION : SHADOWREGION
  1154.                       );
  1155.   { Plot a shadowed rectangle                                                 }
  1156.     var
  1157.       COLOR : integer;
  1158.       SHADOW_LENGTH,
  1159.       SHADOW_HEIGHT,
  1160.       OBJECT_HEIGHT,
  1161.       HEIGHT : real;
  1162.     begin
  1163.       with SHADOW_REGION do
  1164.         begin
  1165.           HEIGHT := MAP[TX,TY]^[XX,YY];
  1166.           COLOR := ALT_TO_COL( round(HEIGHT) );
  1167.  
  1168.           if REMAP_ON
  1169.           then
  1170.             HEIGHT := REMAP_ALT( round(HEIGHT) );
  1171.  
  1172.           if WATER_ON
  1173.           then
  1174.             if HEIGHT < WATER_LINE
  1175.             then
  1176.               HEIGHT := WATER_LINE;
  1177.  
  1178.           SHADOW_LENGTH := (HEIGHT * PMAP_SIZE2) / (RMAXALTITUDE * TANGENT);
  1179.           OBJECT_HEIGHT := HEIGHT * PMAP_SIZE2 / RMAXALTITUDE;
  1180.           SHADOWED_PLOT := true;
  1181.           if (IX + SHADOW_LENGTH) <= (OX + SLENGTH)
  1182.           then
  1183.             begin
  1184.               if IX = MAXX
  1185.               then
  1186.                 SIDE_COLOR
  1187.               else
  1188.                 if IY = MAXY
  1189.                 then
  1190.                   FRONT_COLOR
  1191.                 else
  1192.                   SET_PLOT_COLOR( SHADOW[ COLOR ] );
  1193.  
  1194.               paint_rect( XPNT+(IX*PIXEL_SIZE),
  1195.                           YPNT-round(OBJECT_HEIGHT),
  1196.                           PIXEL_SIZE,    round(OBJECT_HEIGHT)
  1197.                         );
  1198.             end
  1199.           else
  1200.             begin
  1201.               if SLENGTH <= 0
  1202.               then
  1203.                SHADOW_HEIGHT := 0
  1204.               else
  1205.                SHADOW_HEIGHT := (SLENGTH-(IX-OX))*OHEIGHT/SLENGTH;
  1206.  
  1207.               SHADOWED_PLOT := true;
  1208.               if IX = MAXX
  1209.               then
  1210.                 SIDE_COLOR
  1211.               else
  1212.                 if IY = MAXY
  1213.                 then
  1214.                   FRONT_COLOR
  1215.                 else
  1216.                   begin
  1217.                     SHADOWED_PLOT := false;
  1218.                     SET_PLOT_COLOR( LIGHT[ COLOR ] );
  1219.                   end;
  1220.  
  1221.               if round(OBJECT_HEIGHT) > 0
  1222.               then
  1223.                 paint_rect( XPNT+(IX*PIXEL_SIZE),
  1224.                             YPNT-round(OBJECT_HEIGHT),
  1225.                             PIXEL_SIZE, round(OBJECT_HEIGHT)
  1226.                           );
  1227.  
  1228.               SHADOWED_PLOT := true;
  1229.               if IX = MAXX
  1230.               then
  1231.                 SIDE_COLOR
  1232.               else
  1233.                 if IY = MAXY
  1234.                 then
  1235.                   FRONT_COLOR
  1236.                 else
  1237.                   SET_PLOT_COLOR( SHADOW[ COLOR ] );
  1238.  
  1239.               if round(SHADOW_HEIGHT) > 0
  1240.               then
  1241.                 if round(SHADOW_HEIGHT) >= round(OBJECT_HEIGHT)
  1242.                 then
  1243.                   paint_rect( XPNT+(IX*PIXEL_SIZE),
  1244.                               YPNT-round(OBJECT_HEIGHT-1.0),
  1245.                               PIXEL_SIZE,
  1246.                               round(OBJECT_HEIGHT-1.0)
  1247.                             )
  1248.                 else
  1249.                   paint_rect( XPNT+(IX*PIXEL_SIZE),
  1250.                               YPNT-round(SHADOW_HEIGHT),
  1251.                               PIXEL_SIZE,
  1252.                               round(SHADOW_HEIGHT)
  1253.                             );
  1254.  
  1255.               SLENGTH := SHADOW_LENGTH;
  1256.               OHEIGHT := OBJECT_HEIGHT;
  1257.               OX := IX;  OY := IY;
  1258.             end;
  1259.  
  1260.         end;
  1261.     end;
  1262.  
  1263.  
  1264.   function DEG_TO_RAD( DEGREES : real ) : real;
  1265.     begin
  1266.       DEG_TO_RAD := DEGREES * PI / 180.0;
  1267.     end;
  1268.  
  1269.  
  1270.   function GET_TANGENT : real;
  1271.   {                                                                          }
  1272.   { this function gets the angle of the sun and returns the tangent          }
  1273.   {                                                                          }
  1274.     var
  1275.       ANSWER : integer;
  1276.     begin
  1277.       if SHADOW_ON
  1278.       then
  1279.         begin
  1280.           ANSWER := do_alert('[0][| Sun Angle?   |][L|M|H]',2);
  1281.           case ANSWER of
  1282.             1 : SUNANGLE := 15.0;
  1283.             2 : SUNANGLE := 45.0;
  1284.             3 : SUNANGLE := 75.0
  1285.           end;
  1286.         end
  1287.       else
  1288.         SUNANGLE := 90.0;
  1289.  
  1290.       SUNANGLE := DEG_TO_RAD( SUNANGLE );
  1291.       GET_TANGENT := sin( SUNANGLE ) / cos( SUNANGLE );
  1292.     end;
  1293.  
  1294.  
  1295.   procedure SIDE_MAP( var MAP : MAPTYPE );
  1296.   {                                                                         }
  1297.   { this procedure draw an isometric view of the map                        }
  1298.   {                                                                         }
  1299.     var
  1300.       DONE : boolean;
  1301.       HEIGHT,
  1302.       COLOR,
  1303.       XPNT, YPNT,
  1304.       TX, TY, XX, YY,
  1305.       IX, IY,
  1306.       X, Y, W, H : integer;
  1307.       SHADOW_REGION : SHADOWREGION;
  1308.     begin
  1309.       bring_to_front( GRAPHICS_WINDOW );
  1310.       draw_mode( 1 );
  1311.       paint_style( 1 );
  1312.       paint_color( 1 );
  1313.       work_rect( GRAPHICS_WINDOW, X, Y, W, H );
  1314.       set_clip( X, Y, W, H );
  1315.       set_window( GRAPHICS_WINDOW );
  1316.       begin_update; hide_mouse;
  1317.       paint_rect( 0, 0, W, H );
  1318.       DRAW_SCALE;
  1319.       if SHADOW_ON
  1320.       then
  1321.         TANGENT := GET_TANGENT;
  1322.  
  1323.       line_style( 1 );
  1324.       XPNT := WSX + PMAP_SIZE - 1;
  1325.       YPNT := WSY + PMAP_SIZE2 + 2;
  1326.       IY := 0;
  1327.       loop
  1328.         IX := 0;
  1329.         ENLIGHTEN( SHADOW_REGION );
  1330.         TY := (IY div SIDE) + 1;
  1331.         YY := (IY mod SIDE) + 1;
  1332.         if IY = MAXY
  1333.         then
  1334.           begin
  1335.             TY := TY - 1;
  1336.             YY := MAP_SIZE;
  1337.           end;
  1338.  
  1339.         loop
  1340.           TX := (IX div SIDE) + 1;
  1341.           XX := (IX mod SIDE) + 1;
  1342.  
  1343.           if IX = MAXX
  1344.           then
  1345.             begin
  1346.               TX := TX - 1;
  1347.               XX := MAP_SIZE;
  1348.             end;
  1349.  
  1350.           if SHADOW_ON
  1351.           then
  1352.             PLOT_SRECT( MAP, IX, IY, TX, TY, XX, YY,
  1353.                         XPNT, YPNT, MAXX, MAXY,
  1354.                         SHADOW_REGION
  1355.                       )
  1356.           else
  1357.             begin
  1358.               HEIGHT := MAP[TX,TY]^[XX,YY];
  1359.  
  1360.               SHADOWED_PLOT := true;
  1361.               if IY = MAXY
  1362.               then
  1363.                 FRONT_COLOR
  1364.               else
  1365.                 if IX = MAXX
  1366.                 then
  1367.                   SIDE_COLOR
  1368.                 else
  1369.                   SET_PLOT_COLOR( BAND[ ALT_TO_COL( HEIGHT ) ] );
  1370.  
  1371.               if REMAP_ON
  1372.               then
  1373.                 HEIGHT := REMAP_ALT( HEIGHT );
  1374.  
  1375.               if WATER_ON
  1376.               then
  1377.                 if (HEIGHT <= WATER_LINE)
  1378.                 then
  1379.                   HEIGHT := WATER_LINE;
  1380.  
  1381.               HEIGHT := round(((0.0+HEIGHT)*PMAP_SIZE2)/RMAXALTITUDE);
  1382.  
  1383.               paint_rect( XPNT+(IX*PIXEL_SIZE),
  1384.                           YPNT-HEIGHT,
  1385.                           PIXEL_SIZE,
  1386.                           HEIGHT
  1387.                         );
  1388.             end;
  1389.  
  1390.           DONE := QUICK_EXIT;   { check for the mouse button }
  1391.  
  1392.         exit if (IX >= MAXX) or DONE;
  1393.           IX := IX + 1;
  1394.         end;
  1395.  
  1396.         YPNT := YPNT + YINC;
  1397.         if ((YPNT div YINC) & 1) = 0
  1398.         then
  1399.           XPNT := XPNT - PIXEL_SIZE;
  1400.  
  1401.       exit if (IY >= MAXY) or DONE;
  1402.         IY := IY + 1;
  1403.       end;
  1404.  
  1405.  
  1406.       work_rect( GRAPHICS_WINDOW, X, Y, W, H );
  1407.       SAVE_AREA( X, Y, W, H );
  1408.       show_mouse; end_update;
  1409.     end;
  1410.  
  1411. {*****************************************************************************}
  1412.  
  1413.   procedure PLOT_SHADOWED( var MAP : MAPTYPE;
  1414.                                IX, IY, TX, TY, XX, YY : integer;
  1415.                            var SHADOW_REGION : SHADOWREGION
  1416.                          );
  1417.     var
  1418.       COLOR : integer;
  1419.       TEMP_HEIGHT,
  1420.       SHADOW_HEIGHT,
  1421.       SHADOW_LENGTH,
  1422.       HEIGHT : real;
  1423.     begin
  1424.       with SHADOW_REGION do
  1425.         begin
  1426.           if SHADOW_ON
  1427.           then
  1428.             begin
  1429.               HEIGHT := MAP[TX,TY]^[XX,YY];
  1430.               COLOR := ALT_TO_COL( round(HEIGHT) );
  1431.               if REMAP_ON
  1432.               then
  1433.                 HEIGHT := REMAP_ALT( round(HEIGHT) );
  1434.  
  1435.               if WATER_ON
  1436.               then
  1437.                 if HEIGHT < WATER_LINE
  1438.                 then
  1439.                   HEIGHT := WATER_LINE;
  1440.  
  1441.               SHADOW_LENGTH := (HEIGHT * MAP_SIZE) / (RMAXALTITUDE * TANGENT);
  1442.               if (IX + SHADOW_LENGTH) <= (OX + SLENGTH)
  1443.               then
  1444.                 begin
  1445.                   SHADOWED_PLOT := true;
  1446.                   SET_PLOT_COLOR( SHADOW[ COLOR ] );
  1447.                 end
  1448.               else
  1449.                 begin
  1450.                   SHADOWED_PLOT := false;
  1451.                   SET_PLOT_COLOR( LIGHT[ COLOR ] );
  1452.                   SLENGTH := SHADOW_LENGTH;
  1453.                   OHEIGHT := HEIGHT;
  1454.                   OX := IX;  OY := IY;
  1455.                 end;
  1456.             end
  1457.           else
  1458.             SET_PLOT_COLOR( BAND[ALT_TO_COL( round(HEIGHT) )] );
  1459.  
  1460.           paint_rect( WSX+(PIXEL_SIZE*IX),
  1461.                       WSY+(YINC*IY),
  1462.                       PIXEL_SIZE, YINC
  1463.                     );
  1464.         end;
  1465.     end;
  1466.  
  1467.  
  1468.   procedure REDRAW_MAP;
  1469.     var
  1470.       DONE,
  1471.       SAVE_WATCH : boolean;
  1472.       X, Y, W, H,
  1473.       IX, IY, TX, TY, XX, YY : integer;
  1474.       LOCATION : POINT;
  1475.       SHADOW_REGION : SHADOWREGION;
  1476.     begin
  1477.       SAVE_WATCH := WATCH_ON; WATCH_ON := true;
  1478.       bring_to_front( GRAPHICS_WINDOW );
  1479.       line_style( 1 );
  1480.       draw_mode( 1 );
  1481.       paint_style( 1 );
  1482.       work_rect( GRAPHICS_WINDOW, X, Y, W, H );
  1483.       set_clip( X, Y, W, H );
  1484.       set_window( GRAPHICS_WINDOW );
  1485.       begin_update; hide_mouse;
  1486.       if not BRAND_NEW
  1487.       then
  1488.         begin
  1489.           paint_color( 0 );
  1490.           paint_style( 1 );
  1491.           paint_rect( 0, 0, W, H );
  1492.           DRAW_SCALE;
  1493.           CLEAR_MAP_AREA;
  1494.           paint_color( 0 );
  1495.         end;
  1496.  
  1497.       if SHADOW_ON
  1498.       then
  1499.         TANGENT := GET_TANGENT;
  1500.  
  1501.       SHADOWED_PLOT := false;
  1502.       IY := 0;
  1503.       loop
  1504.         TY := (IY div SIDE) + 1;
  1505.         YY := (IY mod SIDE) + 1;
  1506.         if IY = MAXY
  1507.         then
  1508.           begin
  1509.             TY := TY - 1;
  1510.             YY := MAP_SIZE;
  1511.           end;
  1512.  
  1513.         IX := 0;
  1514.         ENLIGHTEN( SHADOW_REGION );
  1515.         loop
  1516.           TX := (IX div SIDE) + 1;
  1517.           XX := (IX mod SIDE) + 1;
  1518.  
  1519.           if IX = MAXX
  1520.           then
  1521.             begin
  1522.               TX := TX - 1;
  1523.               XX := MAP_SIZE;
  1524.             end;
  1525.  
  1526.           if SHADOW_ON
  1527.           then
  1528.             PLOT_SHADOWED( MAP, IX, IY, TX, TY, XX, YY, SHADOW_REGION )
  1529.           else
  1530.             begin
  1531.               WX := WSX + ((TX-1) * SIDE)*PIXEL_SIZE;
  1532.               WY := WSY + ((TY-1) * SIDE)*YINC;
  1533.               LOCATION.X := XX;       LOCATION.Y := YY;
  1534.               PLOT_LOCATION( MAP[TX,TY], LOCATION );
  1535.             end;
  1536.  
  1537.           DONE := QUICK_EXIT;      { check for the mouse button }
  1538.  
  1539.         exit if (IX >= MAXX) or DONE;
  1540.           IX := IX + 1;
  1541.         end;
  1542.  
  1543.       exit if (IY >= MAXY) or DONE;
  1544.         IY := IY + 1
  1545.       end;
  1546.  
  1547.       work_rect( GRAPHICS_WINDOW, X, Y, W, H );
  1548.       SAVE_AREA( X, Y, W, H );
  1549.       WATCH_ON := SAVE_WATCH;
  1550.       show_mouse; end_update;
  1551.     end;
  1552.  
  1553. {*****************************************************************************}
  1554.  
  1555.   procedure GET_SCALE_HEIGHT( var SCALE_HEIGHT : integer );
  1556.     begin
  1557.       SCALE_HEIGHT := do_alert('[0][| Height?    |][L|M|H]',3);
  1558.       case SCALE_HEIGHT of
  1559.         1 : SCALE_HEIGHT := PMAP_SIZE2;
  1560.         2 : SCALE_HEIGHT := (MAP_SIZE*YINC) div 2;
  1561.         3 : SCALE_HEIGHT := MAP_SIZE*YINC;
  1562.       end;
  1563.     end;
  1564.  
  1565.  
  1566.   procedure PERSPECTIVE( var MAP : MAPTYPE );
  1567.     var
  1568.       IX, IY,
  1569.       VHEIGHT, VPERCENT,
  1570.       ALTITUDE,
  1571.       SCALE_HEIGHT,
  1572.       COLOR,
  1573.       TX, TY, XX, YY,
  1574.       X, Y, W, H : integer;
  1575.  
  1576.       LOWER_HEIGHT,
  1577.       LASTX,
  1578.       THISX,
  1579.       OBJECT_HEIGHT,
  1580.       SHADOW_LENGTH,    SHADOW_HEIGHT,
  1581.       SHEIGHT,
  1582.       XORIGIN, YORIGIN, WORIGIN,
  1583.       TPERCENT,
  1584.       HEIGHT : real;
  1585.  
  1586.       DONE,
  1587.       FIRST : boolean;
  1588.  
  1589.       SHADOW_REGION : SHADOWREGION;
  1590.  
  1591.     begin
  1592.       bring_to_front( GRAPHICS_WINDOW );
  1593.       GET_SCALE_HEIGHT( SCALE_HEIGHT );
  1594.       TANGENT := GET_TANGENT;
  1595.       work_rect( GRAPHICS_WINDOW, X, Y, W, H );
  1596.       set_clip( X, Y, W, H );
  1597.       set_window( GRAPHICS_WINDOW );
  1598.       begin_update; hide_mouse;
  1599.       paint_color( 1 );
  1600.       paint_style( 1 );
  1601.       paint_rect( 0, 0, W, H );
  1602.       line_style( 1 );
  1603.       draw_mode( 1 );
  1604.       VHEIGHT := H;
  1605.       VPERCENT := 50;
  1606.  
  1607.       IY := 0;
  1608.       loop
  1609.         TPERCENT := (100.0 - VPERCENT) * (MAXY - IY) / MAXY;
  1610.         XORIGIN  := ((W/2.0) * TPERCENT / 100.0 ) + 1;
  1611.         YORIGIN  := (H+1.0) - (TPERCENT * VHEIGHT / 100.0);
  1612.         WORIGIN  := (100.0 - TPERCENT) * W / 100.0;
  1613.  
  1614.         TY := (IY div SIDE) + 1;
  1615.         YY := (IY mod SIDE) + 1;
  1616.         if IY = MAXY
  1617.         then
  1618.           begin
  1619.             TY := TY - 1;
  1620.             YY := MAP_SIZE;
  1621.           end;
  1622.  
  1623.         ENLIGHTEN( SHADOW_REGION );
  1624.         FIRST := true;
  1625.         IX := 0;
  1626.         loop
  1627.           TX := (IX div SIDE) + 1;
  1628.           XX := (IX mod SIDE) + 1;
  1629.  
  1630.           if IX = MAXX
  1631.           then
  1632.             begin
  1633.               TX := TX - 1;
  1634.               XX := MAP_SIZE;
  1635.             end;
  1636.  
  1637.           ALTITUDE := MAP[TX,TY]^[XX,YY];
  1638.           if WATER_ON and (ALTITUDE < WATER_LINE)
  1639.           then
  1640.             HEIGHT := WATER_LINE
  1641.           else
  1642.             HEIGHT := ALTITUDE;
  1643.  
  1644.           THISX := XORIGIN + (WORIGIN * IX / MAXX);
  1645.           if FIRST
  1646.           then
  1647.             begin
  1648.               FIRST := not FIRST;
  1649.               LASTX := XORIGIN;
  1650.             end;
  1651.  
  1652.           if SHADOW_ON
  1653.           then
  1654.             with SHADOW_REGION do
  1655.               begin
  1656.                 COLOR := ALT_TO_COL( ALTITUDE );
  1657.  
  1658.                 { scale altitude to some convenient value, say, SCALE_HEIGHT }
  1659.                 SHADOW_LENGTH := HEIGHT * SCALE_HEIGHT
  1660.                                  / (RMAXALTITUDE * TANGENT);
  1661.                 OBJECT_HEIGHT := HEIGHT * SCALE_HEIGHT / RMAXALTITUDE;
  1662.  
  1663.                 if (IX + SHADOW_LENGTH) <= (OX + SLENGTH)
  1664.                 then
  1665.                   begin
  1666.                     SHADOWED_PLOT := true;
  1667.                     if IY = MAXY
  1668.                     then
  1669.                       FRONT_COLOR
  1670.                     else
  1671.                       SET_PLOT_COLOR( SHADOW[ COLOR ] );
  1672.  
  1673.                     { scale for distance if enabled }
  1674.                     if SCALE_ON
  1675.                     then
  1676.                       OBJECT_HEIGHT := OBJECT_HEIGHT * (100.0 - TPERCENT)
  1677.                                        / 100.0;
  1678.  
  1679.                     paint_rect( round(LASTX),
  1680.                                 round(YORIGIN)-round(OBJECT_HEIGHT),
  1681.                                 round(THISX)-round(LASTX),
  1682.                                 round(OBJECT_HEIGHT)
  1683.                               );
  1684.                   end
  1685.                 else
  1686.                   begin
  1687.                     if SLENGTH <= 0
  1688.                     then
  1689.                       SHADOW_HEIGHT := 0
  1690.                     else
  1691.                   {    SHADOW_HEIGHT := (SLENGTH-(IX-OX))*OHEIGHT/SLENGTH;  }
  1692.                       SHADOW_HEIGHT := OHEIGHT - ((IX-OX)*OHEIGHT/SLENGTH);
  1693.  
  1694.                     SHADOWED_PLOT := false;
  1695.                     if IY = MAXY
  1696.                     then
  1697.                       FRONT_COLOR
  1698.                     else
  1699.                       SET_PLOT_COLOR( LIGHT[ COLOR ] );
  1700.  
  1701.                     SLENGTH := SHADOW_LENGTH;
  1702.                     OHEIGHT := OBJECT_HEIGHT;
  1703.                     SHEIGHT := SHADOW_HEIGHT;
  1704.                     if SCALE_ON
  1705.                     then
  1706.                       begin
  1707.                       OBJECT_HEIGHT := OBJECT_HEIGHT * (100.0 - TPERCENT)
  1708.                                        / 100.0;
  1709.                       SHADOW_HEIGHT := SHADOW_HEIGHT * (100.0 - TPERCENT)
  1710.                                        / 100.0;
  1711.                       end;
  1712.  
  1713.                     if round(OBJECT_HEIGHT) > 0
  1714.                     then
  1715.                       paint_rect( round(LASTX),
  1716.                                   round(YORIGIN)-round(OBJECT_HEIGHT),
  1717.                                   round(THISX)-round(LASTX),
  1718.                                   round(OBJECT_HEIGHT)
  1719.                                 );
  1720.  
  1721.  
  1722.                     SHADOWED_PLOT := true;
  1723.                     if IY = MAXY
  1724.                     then
  1725.                       FRONT_COLOR
  1726.                     else
  1727.                       SET_PLOT_COLOR( SHADOW[ COLOR ] );
  1728.  
  1729.                     if WATER_ON and
  1730.                        (OHEIGHT > WATER_LINE)
  1731.                     then
  1732.                       if round(SHEIGHT) > 0
  1733.                       then
  1734.                         if round(SHADOW_HEIGHT) >= round(OBJECT_HEIGHT)
  1735.                         then
  1736.                           begin
  1737.                             LOWER_HEIGHT := OBJECT_HEIGHT - FUDGE;
  1738.                             if round(LOWER_HEIGHT) > 0
  1739.                             then
  1740.                               paint_rect( round(LASTX),
  1741.                                           round(YORIGIN)-round(LOWER_HEIGHT),
  1742.                                           round(THISX)-round(LASTX),
  1743.                                           round(LOWER_HEIGHT)
  1744.                                         );
  1745.                           end
  1746.                         else
  1747.                           paint_rect( round(LASTX),
  1748.                                       round(YORIGIN)-round(SHADOW_HEIGHT),
  1749.                                       round(THISX)-round(LASTX),
  1750.                                       round(SHADOW_HEIGHT)
  1751.                                     );
  1752.                     OX := IX;  OY := IY;
  1753.                   end;
  1754.               end
  1755.           else
  1756.             begin
  1757.               { scale altitude to some convenient value, say, SCALE_HEIGHT }
  1758.               HEIGHT := HEIGHT * SCALE_HEIGHT / RMAXALTITUDE ;
  1759.  
  1760.               { scale for distance if enabled }
  1761.               if SCALE_ON
  1762.               then
  1763.                 HEIGHT := HEIGHT * (100.0 - TPERCENT) / 100.0;
  1764.  
  1765.               if (IY = MAXY)
  1766.               then
  1767.                 FRONT_COLOR
  1768.               else
  1769.                 begin
  1770.                   COLOR := ALT_TO_COL( ALTITUDE );
  1771.                   SET_PLOT_COLOR( BAND[ COLOR ] );
  1772.                 end;
  1773.  
  1774.               paint_rect( round(LASTX),
  1775.                           round(YORIGIN)-round(HEIGHT),
  1776.                           round(THISX)-round(LASTX),
  1777.                           round(HEIGHT)
  1778.                         );
  1779.             end;
  1780.  
  1781.           LASTX := THISX;
  1782.           DONE := QUICK_EXIT;  { check for mouse button pressed }
  1783.  
  1784.         exit if (IX >= MAXX) or DONE;
  1785.           IX := IX + 1;
  1786.         end;
  1787.  
  1788.       exit if (IY >= MAXY) or DONE;
  1789.         IY := IY + 1
  1790.       end;
  1791.  
  1792.       work_rect( GRAPHICS_WINDOW, X, Y, W, H );
  1793.       SAVE_AREA( X, Y, W, H );
  1794.       show_mouse; end_update;
  1795.     end;
  1796.  
  1797. {*****************************************************************************}
  1798.  
  1799.   procedure SAVE_MAP( var MAP : MAPTYPE );
  1800.     var
  1801.       I,
  1802.       XX, YY, TX, TY, IX, IY : integer;
  1803.       PATHNAME  : path_name;
  1804.       FPTR      : file of integer; { LONGITUDE; }
  1805.     begin
  1806.       if get_out_file( 'Write to ...', PATHNAME )
  1807.       then
  1808.         begin
  1809.           rewrite( FPTR, PATHNAME );
  1810.           set_mouse( m_bee );
  1811.           if true
  1812.           then
  1813.             begin
  1814.               FPTR^ := NUMXTILES; put( FPTR );
  1815.               FPTR^ := NUMYTILES; put( FPTR );
  1816.  
  1817.               for I := 0 to 15 do
  1818.                 begin
  1819.                   FPTR^ := GET_XCOLOR( I );
  1820.                   put( FPTR );
  1821.                 end;
  1822.  
  1823.               for IY := 0 to MAXY do
  1824.                 begin
  1825.                   TY := (IY div SIDE) + 1;
  1826.                   YY := (IY mod SIDE) + 1;
  1827.                   if IY = MAXY
  1828.                   then
  1829.                     begin
  1830.                       TY := TY - 1;
  1831.                       YY := MAP_SIZE;
  1832.                     end;
  1833.  
  1834.                   for IX := 0 to MAXX do
  1835.                     begin
  1836.                       TX := (IX div SIDE) + 1;
  1837.                       XX := (IX mod SIDE) + 1;
  1838.  
  1839.                       if IX = MAXX
  1840.                       then
  1841.                         begin
  1842.                           TX := TX - 1;
  1843.                           XX := MAP_SIZE;
  1844.                         end;
  1845.  
  1846.                       FPTR^ := MAP[TX,TY]^[XX,YY];
  1847.                       put( FPTR );
  1848.                     end;
  1849.                 end;
  1850.  
  1851.               close( FPTR );
  1852.               INFO_LINE := concat( PATHNAME, '         ' );
  1853.               set_winfo( GRAPHICS_WINDOW,
  1854.                          INFO_LINE
  1855.                        );
  1856.             end
  1857.           else
  1858.             I := do_alert('[2][  I can''t write  |  to that file.  ][oh]',1);
  1859.  
  1860.           set_mouse( m_arrow );
  1861.         end;
  1862.     end;
  1863.  
  1864.  
  1865.   procedure LOAD_MAP( var MAP : MAPTYPE );
  1866.     var
  1867.       I,
  1868.       IX, IY, TX, TY, XX, YY : integer;
  1869.       FPTR : file of integer;
  1870.     begin
  1871.       if get_in_file( DEF_PATH, FILENAME )
  1872.       then
  1873.         begin
  1874.           reset( FPTR, FILENAME );
  1875.           set_mouse( m_bee );
  1876.           NUMXTILES := FPTR^;
  1877.           MAXX := NUMXTILES * SIDE;
  1878.           get( FPTR );
  1879.           NUMYTILES := FPTR^;
  1880.           MAXY := NUMYTILES * SIDE;
  1881.           for I := 0 to 15 do
  1882.             begin
  1883.               get( FPTR );
  1884.               SET_XCOLOR( I, FPTR^ );
  1885.             end;
  1886.  
  1887.           LOWEST := MAXALTITUDE;   HIGHEST := 0;
  1888.           for IY := 0 to MAXY do
  1889.             begin
  1890.               TY := (IY div SIDE) + 1;
  1891.               YY := (IY mod SIDE) + 1;
  1892.               if IY = MAXY
  1893.               then
  1894.                 begin
  1895.                   TY := TY - 1;
  1896.                   YY := MAP_SIZE;
  1897.                 end;
  1898.  
  1899.               for IX := 0 to MAXX do
  1900.                 begin
  1901.                   TX := (IX div SIDE) + 1;
  1902.                   XX := (IX mod SIDE) + 1;
  1903.                   if IX = MAXX
  1904.                   then
  1905.                     begin
  1906.                       TX := TX - 1;
  1907.                       XX := MAP_SIZE;
  1908.                     end;
  1909.  
  1910.                   get( FPTR );
  1911.                   CHECK_RANGE( FPTR^ );
  1912.                   MAP[TX,TY]^[XX,YY] := FPTR^;
  1913.  
  1914.                   if XX = 1
  1915.                   then
  1916.                     if TX <> 1
  1917.                     then
  1918.                       MAP[TX-1,TY]^[MAP_SIZE,YY] := FPTR^;
  1919.  
  1920.                   if YY = 1
  1921.                   then
  1922.                     if TY <> 1
  1923.                     then
  1924.                       MAP[TX,TY-1]^[XX,MAP_SIZE] := FPTR^;
  1925.  
  1926.                 end;
  1927.             end;
  1928.  
  1929.           close( FPTR );
  1930.  
  1931.           INFO_LINE := concat( FILENAME, '         ' );
  1932.           set_winfo( GRAPHICS_WINDOW,
  1933.                      INFO_LINE
  1934.                    );
  1935.           menu_enable( MENU, REMAP_ITEM );
  1936.           REMAP_RANGE := (HIGHEST - LOWEST) + 1;
  1937.  
  1938.           set_mouse( m_arrow );
  1939.         end;
  1940.     end;
  1941.  
  1942.  
  1943.   procedure OLD_LOAD_MAP( var MAP : MAPTYPE );
  1944.     var
  1945.       I,
  1946.       TILEX, TILEY,
  1947.       X, Y : integer;
  1948.       FPTR : file of LONGITUDE;
  1949.     begin
  1950.       if get_in_file( DEF_PATH, FILENAME )
  1951.       then
  1952.         begin
  1953.           reset( FPTR, FILENAME );
  1954.           set_mouse( m_bee );
  1955.           NUMXTILES := FPTR^[ 1 ];
  1956.           MAXX := NUMXTILES * SIDE;
  1957.           NUMYTILES := FPTR^[ 2 ];
  1958.           MAXY := NUMYTILES * SIDE;
  1959.           for I := 0 to 15 do SET_XCOLOR( I, FPTR^[ I + 3 ] );
  1960.           for TILEX := 1 to NUMXTILES do
  1961.             for TILEY := 1 to NUMYTILES do
  1962.               for X := 1 to MAP_SIZE do
  1963.                 begin
  1964.                   get( FPTR );
  1965.                   MAP[TILEX,TILEY]^[X] := FPTR^;
  1966.                 end;
  1967.           close( FPTR );
  1968.           INFO_LINE := concat( FILENAME, '  (old format)' );
  1969.           set_winfo( GRAPHICS_WINDOW,
  1970.                      INFO_LINE
  1971.                    );
  1972.           set_mouse( m_arrow );
  1973.         end;
  1974.     end;
  1975.  
  1976. {*****************************************************************************}
  1977.  
  1978.   procedure DO_VIEW_MENU( ITEM : integer );
  1979.     var
  1980.       CHOICE : integer;
  1981.     begin
  1982.       if ITEM = TOP_ITEM
  1983.       then
  1984.         begin
  1985.           REDRAW_MAP( MAP );
  1986.         end
  1987.       else
  1988.         if ITEM = SIDE_ITEM
  1989.         then
  1990.           SIDE_MAP( MAP )
  1991.         else
  1992.           if ITEM = PERSPEC_ITEM
  1993.           then
  1994.             begin
  1995.               CHOICE := do_alert('[0][|  Scale?    |][Yes|No]',1);
  1996.               SCALE_ON := CHOICE = 1;
  1997.               PERSPECTIVE( MAP );
  1998.             end;
  1999.     end;
  2000.  
  2001.  
  2002.   procedure DO_FILE_MENU( ITEM : integer );
  2003.     begin
  2004.       if ITEM = QUIT_ITEM
  2005.       then
  2006.         begin
  2007.           close_window( GRAPHICS_WINDOW );
  2008.           delete_window( GRAPHICS_WINDOW );
  2009.         end
  2010.       else
  2011.         if ITEM = NEW_ITEM
  2012.         then
  2013.           begin
  2014.             if do_alert('[2][| Are you sure?  |][YES|NO]',2) = 1
  2015.             then
  2016.               begin
  2017.                 INFO_LINE := ' Unnamed map. ';
  2018.                 set_winfo( GRAPHICS_WINDOW,
  2019.                            INFO_LINE
  2020.                          );
  2021.                 DRAW_MAP( MAP );
  2022.                 menu_enable( MENU, SIDE_ITEM );
  2023.                 menu_enable( MENU, TOP_ITEM  );
  2024.                 menu_enable( MENU, PERSPEC_ITEM );
  2025.               end
  2026.           end
  2027.         else
  2028.           if ITEM = OLD_ITEM
  2029.           then
  2030.             begin
  2031.               OLD_LOAD_MAP( MAP );
  2032.               menu_enable( MENU, SIDE_ITEM );
  2033.               menu_enable( MENU, TOP_ITEM  );
  2034.               menu_enable( MENU, PERSPEC_ITEM );
  2035.             end
  2036.           else
  2037.             if ITEM = SAVE_ITEM
  2038.             then
  2039.               SAVE_MAP( MAP )
  2040.             else
  2041.               if ITEM = LOAD_ITEM
  2042.               then
  2043.                 begin
  2044.                   LOAD_MAP( MAP );
  2045.                   SPECIAL_COLORS;
  2046.                   menu_enable( MENU, SIDE_ITEM );
  2047.                   menu_enable( MENU, TOP_ITEM  );
  2048.                   menu_enable( MENU, PERSPEC_ITEM );
  2049.                 end;
  2050.     end;
  2051.  
  2052.  
  2053.   procedure DO_OPTIONS_MENU( ITEM : integer );
  2054.     begin
  2055.     if ITEM = REMAP_ITEM
  2056.     then
  2057.       begin
  2058.         REMAP_ON := not REMAP_ON;
  2059.         menu_check( MENU, REMAP_ITEM, REMAP_ON );
  2060.       end
  2061.     else
  2062.       if ITEM = WATER_ITEM
  2063.       then
  2064.         begin
  2065.           WATER_ON := not WATER_ON;
  2066.           menu_check( MENU, WATER_ITEM, WATER_ON );
  2067.         end
  2068.       else
  2069.         if ITEM = WATCH_ITEM
  2070.         then
  2071.           begin
  2072.             WATCH_ON := not WATCH_ON;
  2073.             menu_check( MENU, WATCH_ITEM, WATCH_ON );
  2074.           end
  2075.         else
  2076.           if ITEM = SHADOW_ITEM
  2077.           then
  2078.             begin
  2079.               SHADOW_ON := not SHADOW_ON;
  2080.               menu_check( MENU, SHADOW_ITEM, SHADOW_ON );
  2081.               SET_NUMBER_OF_LEVELS;
  2082.             end
  2083.           else
  2084.             if ITEM = WIDTH_ITEM
  2085.             then
  2086.               begin
  2087.                 NUMXTILES := do_alert('[0][| Width?    |][1|2|3]',NUMXTILES);
  2088.                 MAXX := NUMXTILES * SIDE;
  2089.               end
  2090.             else
  2091.               if ITEM = HEIGHT_ITEM
  2092.               then
  2093.                 begin
  2094.                   NUMYTILES := do_alert('[0][| Height?   |][1|2]',NUMYTILES);
  2095.                   MAXY := NUMYTILES * SIDE;
  2096.                 end
  2097.               else
  2098.                 if ITEM = RESET_ITEM
  2099.                 then
  2100.                   SPECIAL_COLORS;
  2101.     end;
  2102.  
  2103.  
  2104.   procedure do_redraw( WINDOW, X0, Y0, W0, H0 : integer );
  2105.     var
  2106.       X, Y, W, H : integer;
  2107.     begin
  2108.       set_window(0);
  2109.       begin_update;
  2110.       hide_mouse;
  2111.       first_rect( WINDOW, X, Y, W, H );
  2112.       while (W <> 0) or (H <> 0) do
  2113.         begin
  2114.           if rect_intersect( X0, Y0, W0, H0, X, Y, W, H )
  2115.           then
  2116.             begin
  2117.               RESTORE_AREA( X, Y, W, H );
  2118.             end;
  2119.           next_rect( WINDOW, X, Y, W, H );
  2120.         end;
  2121.       show_mouse;
  2122.       end_update;
  2123.     end;
  2124.  
  2125.  
  2126.   procedure DO_ABOUT;
  2127.     var
  2128.       X, Y, H, W,
  2129.       BUTTON_PRESSED : integer;
  2130.     begin
  2131.       BUTTON_PRESSED := do_dialog( ABOUT_DIALOG, 0 );
  2132.       end_dialog( ABOUT_DIALOG );
  2133.       BUTTON_PRESSED := do_dialog( OSS_DIALOG, 0 );
  2134.       end_dialog( OSS_DIALOG );
  2135.     end;
  2136.  
  2137.  
  2138.   procedure do_menu( TITLE, ITEM : integer );
  2139.     begin
  2140.       if TITLE = VIEW_TITLE
  2141.       then
  2142.         DO_VIEW_MENU( ITEM )
  2143.       else
  2144.         if TITLE = FILE_TITLE
  2145.         then
  2146.           DO_FILE_MENU( ITEM )
  2147.         else
  2148.           if TITLE = OPTIONS_TITLE
  2149.           then
  2150.             DO_OPTIONS_MENU( ITEM )
  2151.           else
  2152.             if TITLE = DESK_TITLE
  2153.             then
  2154.               DO_ABOUT;
  2155.  
  2156.       menu_normal( MENU, TITLE );
  2157.     end;
  2158.  
  2159.  
  2160.  procedure CREATE_MENU;
  2161.     begin
  2162.       MENU := new_menu( 22, '  About TOPMAP  ' );
  2163.       FILE_TITLE    := add_mtitle( MENU, ' File ' );
  2164.       VIEW_TITLE    := add_mtitle( MENU, ' View ' );
  2165.       OPTIONS_TITLE := add_mtitle( MENU, ' Options ' );
  2166.       REMAP_ITEM    := add_mitem( MENU, OPTIONS_TITLE, '  REMAP  ' );
  2167.       SHADOW_ITEM   := add_mitem( MENU, OPTIONS_TITLE, '  SHADOW ' );
  2168.       WATCH_ITEM    := add_mitem( MENU, OPTIONS_TITLE, '  WATCH  ' );
  2169.       WATER_ITEM    := add_mitem( MENU, OPTIONS_TITLE, '  WATER  ' );
  2170.       NULL2_ITEM    := add_mitem( MENU, OPTIONS_TITLE, '~~~~~~~~~' );
  2171.       HEIGHT_ITEM   := add_mitem( MENU, OPTIONS_TITLE, '  HEIGHT ' );
  2172.       WIDTH_ITEM    := add_mitem( MENU, OPTIONS_TITLE, '  WIDTH  ' );
  2173.       RESET_ITEM    := add_mitem( MENU, OPTIONS_TITLE, '  RESET  ' );
  2174.       SIDE_ITEM     := add_mitem( MENU, VIEW_TITLE, '  ISOMETETRIC   ' );
  2175.       TOP_ITEM      := add_mitem( MENU, VIEW_TITLE, '  OVERHEAD      ' );
  2176.       PERSPEC_ITEM  := add_mitem( MENU, VIEW_TITLE, '  PERSPECTIVE   ' );
  2177.       LOAD_ITEM     := add_mitem( MENU, FILE_TITLE, '  LOAD... ' );
  2178.       NEW_ITEM      := add_mitem( MENU, FILE_TITLE, '  NEW     ' );
  2179.       OLD_ITEM      := add_mitem( MENU, FILE_TITLE, '  OLD...  ' );
  2180.       SAVE_ITEM     := add_mitem( MENU, FILE_TITLE, '  SAVE... ' );
  2181.       NULL_ITEM     := add_mitem( MENU, FILE_TITLE, '==========' );
  2182.       QUIT_ITEM     := add_mitem( MENU, FILE_TITLE, '  QUIT    ' );
  2183.       menu_disable( MENU, NULL_ITEM    );
  2184.       menu_disable( MENU, NULL2_ITEM   );
  2185.       menu_disable( MENU, SIDE_ITEM    );
  2186.       menu_disable( MENU, TOP_ITEM     );
  2187.       menu_disable( MENU, PERSPEC_ITEM );
  2188.       menu_disable( MENU, REMAP_ITEM   );
  2189.       REMAP_ON  := false; menu_check( MENU, REMAP_ITEM,  REMAP_ON  );
  2190.       WATER_ON  := true;  menu_check( MENU, WATER_ITEM,  WATER_ON  );
  2191.       WATCH_ON  := true;  menu_check( MENU, WATCH_ITEM,  WATCH_ON  );
  2192.       SHADOW_ON := true;  menu_check( MENU, SHADOW_ITEM, SHADOW_ON );
  2193.       SET_NUMBER_OF_LEVELS;
  2194.     end;
  2195.  
  2196.  
  2197.   procedure CREATE_DIALOGS;
  2198.     var
  2199.       DUMMY : integer;
  2200.       BUFFER : STR255;
  2201.     begin
  2202.       ABOUT_DIALOG := new_dialog(10, 0,0,30,10 );
  2203.       DUMMY  := add_ditem( ABOUT_DIALOG,
  2204.                            g_text, none,
  2205.                            1,1,28,1,
  2206.                            0, $0180
  2207.                          );
  2208.       set_dtext( ABOUT_DIALOG, DUMMY,
  2209.                  'Fractal Topographical Maps', system_font, te_center
  2210.                );
  2211.  
  2212.       DUMMY := add_ditem( ABOUT_DIALOG,
  2213.                           g_text, none,
  2214.                           1,2,28,1,
  2215.                           0, $0180
  2216.                         );
  2217.       BUFFER := 'Copyright   1987';
  2218.       BUFFER[ 11 ] := chr(189);
  2219.       set_dtext( ABOUT_DIALOG, DUMMY,
  2220.                  BUFFER, system_font, te_center
  2221.                );
  2222.  
  2223.       DUMMY := add_ditem( ABOUT_DIALOG,
  2224.                           g_text, none,
  2225.                           1,3,28,1,
  2226.                           0, $0180
  2227.                         );
  2228.       set_dtext( ABOUT_DIALOG, DUMMY,
  2229.                  'by Robert Adam II.', system_font, te_center
  2230.                );
  2231.  
  2232.       DUMMY := add_ditem( ABOUT_DIALOG,
  2233.                           g_text, none,
  2234.                           1,4,28,1,
  2235.                           0, $0180
  2236.                         );
  2237.       set_dtext( ABOUT_DIALOG, DUMMY,
  2238.                  'All rights reserved.', system_font, te_center
  2239.                );
  2240.  
  2241.       DUMMY := add_ditem( ABOUT_DIALOG,
  2242.                           g_text, none,
  2243.                           1,5,28,1,
  2244.                           0, $0180
  2245.                         );
  2246.       set_dtext( ABOUT_DIALOG, DUMMY,
  2247.                  'You may give it away,', system_font, te_center
  2248.                );
  2249.  
  2250.       DUMMY := add_ditem( ABOUT_DIALOG,
  2251.                           g_text, none,
  2252.                           1,6,28,1,
  2253.                           0, $0180
  2254.                         );
  2255.       set_dtext( ABOUT_DIALOG, DUMMY,
  2256.                  'but not sell it.', system_font, te_center
  2257.                );
  2258.  
  2259.       DUMMY        := add_ditem( ABOUT_DIALOG,
  2260.                                  g_button, touch_exit | default,
  2261.                                  14,8,2,1,
  2262.                                  0, $0180
  2263.                                );
  2264.       set_dtext( ABOUT_DIALOG, DUMMY,
  2265.                  'ok', system_font, te_center
  2266.                );
  2267.       center_dialog( ABOUT_DIALOG );
  2268.  
  2269.  
  2270.       OSS_DIALOG := new_dialog(10, 0,0,30,10 );
  2271.  
  2272.       DUMMY := add_ditem( OSS_DIALOG,
  2273.                           g_text, none,
  2274.                           1,1,28,1,
  2275.                           0, $0180
  2276.                         );
  2277.       set_dtext( OSS_DIALOG, DUMMY,
  2278.                  'Portions of this product are',
  2279.                  system_font, te_center
  2280.                );
  2281.       DUMMY := add_ditem( OSS_DIALOG,
  2282.                           g_text, none,
  2283.                           1,2,28,1,
  2284.                           0, $0180
  2285.                         );
  2286.       BUFFER := 'Copyright   1986';
  2287.       BUFFER[ 11 ] := chr(189);
  2288.       set_dtext( OSS_DIALOG, DUMMY,
  2289.                  BUFFER,
  2290.                  system_font, te_center
  2291.                );
  2292.       DUMMY := add_ditem( OSS_DIALOG,
  2293.                           g_text, none,
  2294.                           1,3,28,1,
  2295.                           0, $0180
  2296.                         );
  2297.       set_dtext( OSS_DIALOG, DUMMY,
  2298.                  'OSS and CDD.',
  2299.                  system_font, te_center
  2300.                );
  2301.       DUMMY := add_ditem( OSS_DIALOG,
  2302.                           g_text, none,
  2303.                           1,4,28,1,
  2304.                           0, $0180
  2305.                         );
  2306.       set_dtext( OSS_DIALOG, DUMMY,
  2307.                  'Used by permission of OSS.',
  2308.                  system_font, te_center
  2309.                );
  2310.       DUMMY        := add_ditem( OSS_DIALOG,
  2311.                                  g_button, touch_exit | default,
  2312.                                  14,8,2,1,
  2313.                                  0, $0180
  2314.                                );
  2315.       set_dtext( OSS_DIALOG, DUMMY,
  2316.                  'ok', system_font, te_center
  2317.                );
  2318.       center_dialog( OSS_DIALOG );
  2319.     end;
  2320.  
  2321.  
  2322.   procedure CREATE_GWINDOW;
  2323.     begin
  2324.       MAIN_TITLE := COPYRIGHT1;
  2325.       GRAPHICS_WINDOW := new_window( g_name | g_info,
  2326.                                      MAIN_TITLE,
  2327.                                      0, 0, 0, 0
  2328.                                    );
  2329.       open_window( GRAPHICS_WINDOW,
  2330.                    0, 0, 0, 0
  2331.                  );
  2332.       INFO_LINE := ' No map.  ';
  2333.       set_winfo( GRAPHICS_WINDOW,
  2334.                  INFO_LINE
  2335.                );
  2336.  
  2337.       INIT_GWINDOW;
  2338.  
  2339.     end;
  2340.  
  2341.  
  2342.   procedure EVENT_LOOP;
  2343.  
  2344.     var
  2345.       WHICH : integer ;
  2346.       MSG   : message_buffer ;
  2347.  
  2348.     begin
  2349.       repeat
  2350.         WHICH := get_event( e_message, 0, 0, 0, 0,
  2351.                 false, 0, 0, 0, 0, false, 0, 0, 0, 0, msg,
  2352.                 dummy, dummy, dummy, dummy, dummy, dummy ) ;
  2353.         case msg[0] of
  2354.           mn_selected: DO_MENU( msg[3], msg[4] );
  2355.           wm_topped:
  2356.             bring_to_front( msg[3] ) ;
  2357.           wm_redraw:
  2358.              do_redraw( msg[3], msg[4], msg[5], msg[6], msg[7] ) ;
  2359.           wm_sized, wm_moved:
  2360.             set_wsize( msg[3], msg[4], msg[5], msg[6], msg[7] ) ;
  2361.           wm_closed:
  2362.             begin
  2363.               close_window( msg[3] ) ;
  2364.               delete_window( msg[3] ) ;
  2365.             end;
  2366.         end;
  2367.       until (msg[3] = FILE_TITLE) and (msg[4] = QUIT_ITEM)
  2368.     end;
  2369.  
  2370.  
  2371.   procedure ALLOCATE;
  2372.   { Allocate the space for the saved screen, the MFDBs and the map        }
  2373.     var
  2374.       TILEX, TILEY : integer;
  2375.     begin
  2376.       new( MEMORY );
  2377.       new( S_MFDB );
  2378.       new( D_MFDB );
  2379.       for TILEX := 1 to MAXXTILES do
  2380.         for TILEY := 1 to MAXYTILES do
  2381.           new( MAP[ TILEX, TILEY ] );
  2382.       READY_MFDB;
  2383.     end;
  2384.  
  2385.   procedure SETUP_FOR_REZ;
  2386.     var
  2387.       DUMMY : integer;
  2388.     begin
  2389.       REZ := GETREZ;
  2390.  
  2391.       case REZ of
  2392.         0 : begin
  2393.               FUDGE       := 1.0;
  2394.               PIXEL_SIZE  := 1;
  2395.               NUM_PLANES  := 4;
  2396.               YINC        := 1;
  2397.               SCALEX      := 290;
  2398.               SCALEY      := WSY;
  2399.               SCALEW      := 15;
  2400.               SCALEH      := 130;
  2401.             end;
  2402.         1 : begin
  2403.               FUDGE       := 1.5;
  2404.               PIXEL_SIZE  := 2;
  2405.               NUM_PLANES  := 2;
  2406.               YINC        := 1;
  2407.               SCALEX      := 290*2;
  2408.               SCALEY      := WSY;
  2409.               SCALEW      := 15*2;
  2410.               SCALEH      := 130;
  2411.             end;
  2412.         2 : begin
  2413.               FUDGE       := 4.0;
  2414.               PIXEL_SIZE  := 2;
  2415.               NUM_PLANES  := 1;
  2416.               YINC        := 2;
  2417.               SCALEX      := 290*2;
  2418.               SCALEY      := WSY*2;
  2419.               SCALEW      := 15*2;
  2420.               SCALEH      := 130*2;
  2421.             end;
  2422.       end;
  2423.  
  2424.       PMAP_SIZE   := MAP_SIZE * PIXEL_SIZE;
  2425.       PMAP_SIZE2  := 28 * YINC;
  2426.     end;
  2427.  
  2428. {}
  2429. { ... The main program ... }
  2430. {}
  2431.  
  2432.   begin
  2433.     if init_gem >= 0
  2434.     then
  2435.       begin
  2436.       { set up the global parameter variables }
  2437.         SETUP_FOR_REZ;
  2438.         NUMLEVELS   := 7;
  2439.         SAVE_COLORS;
  2440.         DEF_PATH    := 'B:\*.MAP';
  2441.         WX          := WSX;
  2442.         WY          := WSY;
  2443.         NUMXTILES   := MAXXTILES;
  2444.         NUMYTILES   := MAXYTILES;
  2445.         SIDE        := MAP_SIZE - 1;
  2446.         MAXX        := NUMXTILES * SIDE;
  2447.         MAXY        := NUMYTILES * SIDE;
  2448.         BRAND_NEW   := false;
  2449.         border_rect( 0, XSCRN, YSCRN, WSCRN, HSCRN );
  2450.         ALLOCATE;  { the pointer variables }
  2451.  
  2452.       { create the dialogs and menu }
  2453.         set_mouse( m_bee );
  2454.         init_mouse;
  2455.         CREATE_MENU;
  2456.         CREATE_DIALOGS;
  2457.         hide_mouse;
  2458.  
  2459.       {   set the colors that are used to display the maps and initialize the }
  2460.       {  the global parameter variables that are associated with the colors   }
  2461.         SET_SPECIAL_COLORS;
  2462.  
  2463.       { create the window to be used to display the maps }
  2464.         CREATE_GWINDOW;
  2465.  
  2466.         set_mouse( m_bee );
  2467.         show_mouse;
  2468.  
  2469.       { display the menu.  This seems to take a few seconds to do. }
  2470.         draw_menu( MENU ) ;
  2471.  
  2472.         set_mouse( m_arrow );
  2473.  
  2474.       { wait for an event }
  2475.         EVENT_LOOP;
  2476.  
  2477.       { dispose of the menu }
  2478.         erase_menu( MENU ) ;
  2479.  
  2480.       { return the colors to the what they were before I changed them }
  2481.         RESTORE_COLORS;
  2482.         exit_gem;
  2483.       end;
  2484.   end.
  2485.